建造者模式提供对象的灵活构建
建造者设计模式将一个复杂对象的构造与它的表示分离,使同样的构建过程可以创建不同的表示
怎么理解这句话呢?其实多读两遍也就理解了,我们知道对象是由多个属性构造的,尤其是构造一个复杂对象,那么它包含的属性更多,比如我现在构建一个Person对象。
思考一下Person对象有哪些属性呢?姓名、年龄、性别、爱好、学历等。其中姓名、年龄和性别那是必要属性,没它不行啊。至于爱好、学历可有无,那么Person类声明如下
public class Person{
String name; //姓名
int age; //年龄
char sex; //性别
String hobby; //爱好
String education; //学历
public Person(){
}
// 1.没有爱好,没有学历
public Person(String name,int age,char sex){
...
}
// 2.有爱好,没学历
public Person(String name,int age,char sex,String hobby){
...
}
//3.有学历,没爱好
public Person(String name,int age,char sex,String education){
...
}
//4.有学历,有爱好
public Person(String name,int age,char sex,String hobby,String education){
...
}
}
那么有这几类人,1.没有爱好,没有学历;2.有爱好,没学历;3.有学历,没爱好;4.有学历,有爱好
那么衍生出了四类构造方法,如上所示,如果我需要创建上述几类Person对象,那么需要调用以上构造方法,这里如果Person属性之后继续扩展,还需要另外定义构造方法…
传统模式构建复杂对象缺点
- 构造方法重载太多,不利于阅读
- 方法参数过长,调用起来过于麻烦,时间一长,可能忘记具体参数的含义,可能会传错参数
- 对象的创建和它的表示严重耦合
基于以上各种弊端,建造者设计模式来了,说白了,它就是告诉我们怎么优雅的创建一个复杂对象。
// Person类建造者模式写法
public class Person{
String name;
int age;
char sex;
String hobby;
String education;
private Person(Builder builder){
this.name = builder.name;
this.age = builder.age;
this.sex = builder.sex;
this.hobby = builder.hobby;
this.education = builder.education;
}
public static final class Builder{
String name;
int age;
char sex;
String hobby;
String education;
public Builder(String name,int age,char sex){
this.name = name;
this.age = age;
this.sex = sex;
}
public Builder hobby(String hobby){
this.hobby = hobby;
return this;
}
public Builder education(String education){
this.education = education;
return this;
}
public Person create(Builder builder){
return new Person(Builder builder);
}
}
}
这样以来,我再次创建上述几类对象,就很方便了
Person p1 = new Person.Builder("zhangsan",24,'M').create();
Person p2 = new Person.Builder("zhangsan",24,'M').hobby("篮球").education("本科").create();
...
建造者模式优缺点:
优点:
- 可读性非常强,比如hobby(“篮球”),这个就是用来构造爱好属性的,等等,一目了然
- 将对象的创建与表示分离了,看到没,对象的创建全程是由Builder来做,然后Person直接显示就好了
- 后续扩展属性,依然很方便,而且可维护性比较高
当然事物都有两面性,带来好处的同时,也带来了一些缺点
- 首先我们要多创建一个Builder对象吧
- 其次Builder代码也写了不少,后期加属性,改动的地方也比较多,但是这种改动都是扩展,相对较安全
我们的逻辑代码也不是越少越好,越容易理解,可读性好,易维护才是好代码
所以设计模式有时候不一定带来便利,我们重要的理解它的设计思想,在复杂逻辑中,通过它可以更好的优化我们的逻辑设计,使得更容易维护和扩展。所以一些简单的逻辑,也没必要非用设计模式套,适得其反。
使用场景?
对象构建比较复杂,属性很多,而且存在很多可选的属性。 比如著名的图片框架Glide,图片的加载配置,就用了Builder设计模式,因为图片的配置很多,可选属性也很多,那么就这个场景就非常适用这个建造者模式。类似的还有著名的网络框架OkHttp,OkHttpClient的创建也是利用了建造者模式。还有Android中的AlertDialog的构建等…