构建者模式

  • 定义
  • 实现
  • 角色
  • 代码演示
  • Android中构建者模式的样例
  • AlertDialog
  • Notification
  • OKHttp
  • 优点


定义

又称为建造者模式,它是将一个复杂对象的创建和表示进行分离,使得同样的构建过程可以创建不同的表示

怎么理解这句话呢?

比如你要组装一辆汽车,那肯定是需要很多工具和零部件的,然后你不管三七二十一,跑到库房去,面对着一屋子的零件,你是不是懵逼了,我该怎么从这一堆东西里找到组装一辆车需要的零件;然后现在组装模式升级了,有一个专门和你对接的老司机,你只要告诉他这一步需要什么零件,下一步需要什么零件,老司机去帮你组装,你完全不需要关心库房里有多少乱七八糟的东西;这样你想组装出什么样的车子,只要依次告诉老司机就行了

这个比喻可能不是太恰当,但是道理应该还是挺清楚的:

车子这个对象的创建应该说是挺复杂的,它有非常多的属性,你如果直接通过构造方法传参去创建实例,那想必是不能忍受的;但是你如果使用对外公开的创建者角色,也就是上面的老司机,然后想传什么属性值就给它,直到你想完了,最后一构建,车子就出来了

实现

角色

构建者模式下有两个角色是必须要存在的,当然了按照规范来实现会有四个角色,我们这里就简述

  • Product:即最终要构建的对象,内部包含复杂或者大量的属性
  • Builder:真正的构建者对象,针对不同的业务需求,实现了对复杂对象的不同显示的创建

不带代码的讲解都是耍流氓,接下来通过代码演示

代码演示

现在有【人】这么个对象,既然是人,那肯定就有很多属性,如下

public class Person {

    private String age;
    private String sex;
    private String name;
    private String weight;
    private String height;
    private String location;
    private String idCard;
    private String workType;
    private String school;
    private String father;
    private String mother;
    private String favorite;
    private String skill;


}

这里只是举例,实际开发者你需要用到的对象可能有更多的属性,比如OKHttpClient对象;如果你通过构造方法传参的形式或者通过setXXX方法去构造一个对象,显然是没有人性的,对程序猿太残忍了,麻烦不说写法还巨丑无比;这时候就需要使用构建者模式

我们要做的就是新增一个内部类Builder,当然你也可以单独写一个类:

  • 在其内部定义同样的属性,并增加相应的setXX方法,但是切记每个setXXX方法要返回Builder对象,便于实现链式编程
  • 提供一个无参的构造方法,可以在里面指定一些属性的默认值
  • 对外公开一个build方法,用来实例化Person对象并返回
public static final class Builder{

        private String age;
        private String sex;
        private String name;
        private String weight;
        private String height;
        private String location;
        private String idCard;
        private String workType;
        private String school;
        private String father;
        private String mother;
        private String favorite;
        private String skill;

        public Builder() {
            //这里可以给一些属性添加默认值
            age = "15";
        }

        public Builder setAge(String age) {
            this.age = age;
            return this;
        }

        public Builder setSex(String sex) {
            this.sex = sex;
            return this;
        }

        public Builder setName(String name) {
            this.name = name;
            return this;
        }

        public Builder setWeight(String weight) {
            this.weight = weight;
            return this;
        }

        public Builder setHeight(String height) {
            this.height = height;
            return this;
        }

        public Builder setLocation(String location) {
            this.location = location;
            return this;
        }

        public Builder setIdCard(String idCard) {
            this.idCard = idCard;
            return this;
        }

        public Builder setWorkType(String workType) {
            this.workType = workType;
            return this;
        }

        public Builder setSchool(String school) {
            this.school = school;
            return this;
        }

        public Builder setFather(String father) {
            this.father = father;
            return this;
        }

        public Builder setMother(String mother) {
            this.mother = mother;
            return this;
        }

        public Builder setFavorite(String favorite) {
            this.favorite = favorite;
            return this;
        }

        public Builder setSkill(String skill) {
            this.skill = skill;
            return this;
        }

        public Person build(){
            return new Person(this);
        }
    }

接下来要给Person对象添加构造方法,接收Builder对象,然后给内部属性赋值

public Person() {
        this(new Builder());
    }

    public Person(Builder builder) {
        age = builder.age;
        sex = builder.sex;
        name = builder.name;
        weight = builder.weight;
        height = builder.height;
        location = builder.location;
        idCard = builder.idCard;
        workType = builder.workType;
        school = builder.school;
        father = builder.father;
        mother = builder.mother;
        favorite = builder.favorite;
        skill = builder.skill;
    }

最后就是使用了:

Person person = new Person
        .Builder()
        .setAge("15")
        .setName("Jon")
        .setSex("1")
        .build();

相比于在构造方法传参和一些列的set方法,这种写法是不是很简洁,你想传什么参数就在.Builder()后面追加就行了

Android中构建者模式的样例

AlertDialog

AlertDialog dialog = new AlertDialog
              .Builder(this)
              .setIcon(R.mipmap.ic_launcher)
              .setTitle("弹框")
              .setPositiveButton()
              .setNegativeButton()
              .create();

Notification

Notification notification = new Notification
                  .Builder(this)
                  .setContentTitle("通知")
                  .setContentText("你收到了一条消息")
                  .setSmallIcon(R.mipmap.ic_launcher)
                  .build();

OKHttp

OkHttpClient client = new OkHttpClient
        .Builder()
        .readTimeout(5000, TimeUnit.MILLISECONDS)
        .writeTimeout(5000,TimeUnit.MILLISECONDS)
        .cache(new Cache(new File("cache"), 1024 * 1024 * 10))
        .build();

优点

  • 写法简洁,代码优美
  • 开发者无需了解对象内部组成的细节,只用关心自己需要什么样的对象