安卓设计模式之建造者模式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;
        }

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值