使用场景:
- 构造对象需要大量可选的参数,
- 参数个数不确定,日后可能会修改,最好一开始就使用构建器模式
构造方法构造的缺点:
通常构造对象时,我们会采用构造函数的方式来对对象的参数进行初始化,例如:
Person person1=new Person("apollo",27,"男",null,"黄皮肤","本科","山西");
问题1:可读性很差,程序员必须很清楚构造函数中各个参数是什么及其顺序,代码可读性随参数个数的增加急速下降,想读懂基本靠文档
问题2:设置参数不灵活,为了要给靠后的参数赋值,必须设置一遍不需要设置的参数
Person person2=new Person("apollo",null,null,null,null,null,"山西");
使用JavaBean代替构造方法:
估计使用java的人都写过上面的代码,为了解决以上问题,大家经常使用javabean的形式构造对象:
Person person=new Person();
person.setName("apollo");
person.setBirthplace("山西");
System.out.println(person.getName());
javabean大大增强了对象参数初始化的可读性,并且不必遵循类似构造函数那样的参数顺序,但是javabean的格式注定了对象不可能是不可变的(Immutable),可变对象在多线程环境下需要解决线程安全问题。
使用构造器构造对象:
构造器模式则是兼具了构造函数的线程安全性和JavaBeans可读性优点。
使用builder对象调用类似于setter的方法,来设置每个相关的可选参数。最后,用无参的build方法来生成对象。通常,这个builder是它构造的类的静态成员类。
public class Person {
private String name;
private Integer age;
private String sex;
private String country;
private String skinColor;
private String education;
private String birthplace;
public Person() {
}
public Person(Builder builder) {
this.name=builder.name;
this.age=builder.age;
this.sex=builder.sex;
this.country=builder.country;
this.skinColor=builder.skinColor;
this.birthplace=builder.birthplace;
this.education=builder.education;
}
static class Builder {
private String name;
private Integer age;
private String sex;
private String country;
private String skinColor;
private String education;
private String birthplace;
public Builder name(String name) {
this.name = name;
return this;
}
public Builder age(Integer age) {
this.age = age;
return this;
}
public Builder sex(String sex) {
this.sex = sex;
return this;
}
public Builder country(String country) {
this.country = country;
return this;
}
public Builder skinColor(String skinColor) {
this.skinColor = skinColor;
return this;
}
public Builder education(String education) {
this.education = education;
return this;
}
public Builder birthplace(String birthplace) {
this.birthplace = birthplace;
return this;
}
public Person build(){
return new Person(this);
}
}
public String getName() {
return name;
}
}
构造对象语句:
Person person=new Person.Builder()
.name("apollo")
.birthplace("山西")
.build();
System.out.println(person.getName());