静态工厂和构造器都有个共同的局限性,不能很好的扩展大量的可选参数。
对于多种参数的类,我们一向习惯于使用重叠构造器,不同的构造器提供不同的参数,这种构造器模式可行,但是代码难以阅读,客户端代码难以编写。
public class Peopel {
private String name;
private String sex;
private String birthday;
public Peopel() {
}
public Peopel(String name,String sex){
this.name=name;
this.sex=sex;
}
public Peopel(String name,String sex,String birthday){
this.name=name;
this.sex=sex;
this.birthday=birthday;
}
}
遇到多构造参数的时候,我们还经常使用javabeans模式,在这种模式下,调用一个无参构造函数创建对象,然后使用setter方法来设置每个必要的参数。这样实现的代码创建实例容易,代码阅读也容易。但是,因为构造过程被分到几个调用中,这会使得javabean处于不一致的状态。另外Javabean模式阻止了把类做成不可变的可能,这需要我们自己实现线程安全。
public class PeopleBean {
private String name;
private String sex;
private String birthday;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getBirthday() {
return birthday;
}
public void setBirthday(String birthday) {
this.birthday = birthday;
}
}
还有一种方式,就是构建器模式(Builder模式),既能保证重叠构造器的安全性,也能保证Javabeans模式的可读性。它不会直接生成想要的对象,而是让客户端利用所有的参数调用构造器,得到builder对象,然后在builder对象上调用类似于setter方法,来设置每个可选参数。
public class PeopleBuilder {
private final String name;
private final String sex;
private final String birthday;
public static class Builder {
private final String name;
private String sex;
private String birthday;
public Builder(String name) {
this.name = name;
}
public Builder sex(String val) {
sex = val;
return this;
}
public Builder birthday(String val) {
birthday = val;
return this;
}
public PeopleBuilder build() {
return new PeopleBuilder(this);
}
}
private PeopleBuilder(Builder builder) {
name = builder.name;
sex = builder.sex;
birthday = builder.birthday;
}
}
调用:
public static void main(String[] args) {
PeopleBuilder pb=new PeopleBuilder.Builder("呵呵").sex("男").birthday("1996").build();
}
Builder 模式也有它自己的不足,为了创建对象,必须创建它自己的构造器,构造器模式比较冗长,只能在参数很多时使用。