静态工厂和构造器都有个共同的局限性,不能很好的扩展大量的可选参数。
对于多种参数的类,我们一向习惯于使用重叠构造器,不同的构造器提供不同的参数,这种构造器模式可行,但是代码难以阅读,客户端代码难以编写。
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 模式也有它自己的不足,为了创建对象,必须创建它自己的构造器,构造器模式比较冗长,只能在参数很多时使用。