安卓设计模式之建造者模式Builder

Builder模式是安卓开发中一种常见的设计模式,这里我们简单介绍一下。

Builder的定义

将一个复杂对象的构造与他的表示分离,使得同样的构造过程可以创建不同的表示。

Builder的使用

Builder设计模式的代码长什么样子,先来大致看一下:

  new AlertDialog.Builder(this)

                .setTitle("the title")

                .setMessage("the message")

                .setCancelable(true)

                .create()

                .show();

很优雅有木有,这个链式调用就是Builder一个很明显的特征,可读性非常强。

我们在什么情况下适合用Builder模式呢?

当我们要创建一个类时,并且这个类中有很多属性且有一部分是可选属性,那么这时候我们就可以使用Builder模式。

这里先贴一个使用Builder的一个demo类,如下:

public class Student {

    private final String name;

    private final String age;

    private final String phone;

    private final String address;

    private Student(Builder builder){

            this.name=builder.name;

            this.address=builder.address;

            this.age=builder.age;

            this.phone=builder.phone;

    }

    public String getName() {

            return name;

    }

    public String getAge() {

            return age;

    }

    public String getPhone() {

            return phone;

    }

    public String getAddress() {

            return address;

    }

    public static class Builder{

        private final String name;

        private final String age;

        private  String phone;

        private  String address;

        public Builder(String name, String age) {

                this.name = name;

                this.age = age;

        }

        public Builder phone(String phone){

                this.phone=phone;

                return this;

        }

        public Builder address(String address){

                this.address=address;

                return this;

        }

        public Student build(){

                return new Student(this);

        }

    }

}

使用时:

  new Student.Builder("小明", "26")

                .phone("183***")

                .address("西湖区")

                .build();

我们来看上面这个Student类

这个Student类的构造方法设置成了private,说明调用者不能直接创建Student对象。Student类中有一个静态内部类Builder,Student类有四个属性,我们都设置成了final,只提供getter方法。并且在构造方法中对他们进行了初始化。构造方法中只有一个参数就是Builder对象,我们Student对象的创建就在Builder中的build方法中。所以总的来说我们是使用Builder 对象来创建Student对象。

接下来看这个静态内部类Builder

Builder类中的属性和Student是一致的,有几个方法很明显是分别设置几个属性的,这几个方法的返回值都是Builder本身,这是为了链式调用。Builder类的构造方法中有两个参数,说明有两个属性是必传的。其他的参数就可以使用链式调用按需设置了。当属性设置完毕之后就是调用build方法了,在build方法中创建了Student对象。这时我们要创建Student对象的目的也就完成了。

这样来创建对象不仅可读性强,而且build()方法可以明确的告诉别人对象已经创建完毕。特别优雅。

对于这种有可选属性的对象来说用Builder模式来创建对象有很明显的优势。下面是两种传统写法:

1. 需要写很多参数不同的构造方法,想想就恶心。

2. 先利用无参构造方法创建一个对象,再使用setter()方法把需要的参数set进去。这样也有明显的缺点,一个是对象创建没有一个明显的结束标志,有可能会在对象需要的属性还没完全set进去之前就被调用,这就会出现问题了。另一个是这样创建的这个对象就是可变的了,也就是说在我们创建好的基础上继续改变它,给它set新的属性或者删除某个已经set的属性等。

Builder线程安全问题

Builder是非线程安全的,所以要对参数做合法性验证的话必需要在对象创建完成之后再检查。

正确的代码示例是:

  public Student build(){

            Student stu=new Student(this);

            if(stu.getName().equals("二狗")){

                    throw new IllegalStateException("这里不允许叫二狗");

            }

                return stu;

        }

一定要先创建对象再进行参数验证,因为如果先验证后创建对象的话,创建的对象的时候对象的属性可能已经被其他线程改变了。

你可能感兴趣的:(安卓设计模式之建造者模式Builder)