设计模式之Builder模式
2019-03-03 本文已影响0人
忧零520
构建者(Builder)设计模式(又叫生成器设计模式)
创建一个对象时,当需要多余三个参数,并且这些参数有些是可选的参数时,考虑使用Builder模式。它的好处就是提高了可读性,不用对单个变量进行注释,降低使用者的学习成本,要的东西也能都很好设置进来,这就是Builder模式的应用场景,Builder模式可以将一个类的构建和表示进行分离。
我们来看一个例子:
public class Student {
private String name;//必须
private int sex;//必须
private int age;//可选
private String address;//可选
private String hobby;//可选
private Student(Builder builder)
{
this.name = builder.name;
this.age = builder.age;
this.sex = builder.sex;
this.address = builder.address;
this.hobby = builder.hobby;
}
public static final class Builder
{
private String name;
private int age;
private int sex;
private String address;
private String hobby;
public Builder(String name,int sex)
{
this.name = name;
this.sex = sex;
this.age = 19;
this.address = "上海省北京市深圳县天津镇重庆区";
this.hobby = "抽烟、喝酒、打麻将、睡觉";
}
public Builder setAge(int age) {
this.age = age;
return this;
}
public Builder setAddress(String address) {
this.address = address;
return this;
}
public Builder setHobby(String hobby) {
this.hobby = hobby;
return this;
}
public Student build()
{
return new Student(this);
}
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
", address='" + address + '\'' +
", hobby='" + hobby + '\'' +
'}';
}
}
使用:
public class StudentMain {
public final static void main(String [] args)
{
Student student = new Student.Builder("李四",1)
.setAge(22)
.build();
System.out.println(student);
}
}
如果我们不用Builder模式
我们可以用多个构造方法:
public class Student {
private String name;//必须
private int sex;//必须
private int age;//可选
private String address;//可选
private String hobby;//可选
public Student(int age, String address) {
this.age = age;
this.address = address;
}
public Student(int age, String address, String hobby) {
this.age = age;
this.address = address;
this.hobby = hobby;
}
public Student(String name, int age, String address, String hobby) {
this.name = name;
this.age = age;
this.address = address;
this.hobby = hobby;
}
省略若干构造方法......
也可以用多个setter:
public class Student {
private String name;//必须
private int sex;//必须
private int age;//可选
private String address;//可选
private String hobby;//可选
public Student(int age, String address) {
this.age = age;
this.address = address;
}
public void setAge(int age) {
this.age = age;
}
public void setAddress(String address) {
this.address = address;
}
省略若干代码......
那么这两种方式有什么弊端呢?
第一种主要是使用及阅读不方便。你可以想象一下,当你要调用一个类的构造函数时,你首先要决定使用哪一个,然后里面又是一堆参数,如果这些参数的类型很多又都一样,你还要搞清楚这些参数的含义,很容易就传混了,那酸爽谁用谁知道。
第二种方式在构建过程中对象的状态容易发生变化,造成错误。因为那个类中的属性是分步设置的,所以就容易出错。
为了解决这两个痛点,builder模式就横空出世了
总结:
1.Builder模式将表示和构建分离开来,将复杂对象构建过程模块化,解耦
2.直接set方法链式调用,如果在多线程中,会有对象状态不一致的情况,
而Builder模式中,只要builder是局部变量,保证其对象一致,那么构建出的原始对象也是状态一致的