静态工厂和构造器都有一个共同的局限性:他们都不能很好地扩展到大量的可选参数,例如有一个对象,有20个可选参数,如果使用静态工厂或者构造器就有可能需要写20个不同参数个数的构建实例的方法,这样的方式称为重叠构造。
重叠构造器模式虽然说是可行的,但是当参数很多很多的时候,客户端代码会很难编写。
这个时候还有第二种方法,就是JavaBeans模式,这种模式下调用无参构造函数,然后为每一个参数设置一个setter方法,如下:
public class NutritionFacts {
private int servingSize = 1;
private int servings = 0;
private int fat = 0;
private int age = 0;
private String name;
private String sex;
private String address;
private double score;
private String bodyId;
public NutritionFacts(){};
public void setServingSize(int servingSize) {
this.servingSize = servingSize;
}
public void setServings(int servings) {
this.servings = servings;
}
public void setFat(int fat) {
this.fat = fat;
}
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setSex(String sex) {
this.sex = sex;
}
public void setAddress(String address) {
this.address = address;
}
public void setScore(double score) {
this.score = score;
}
public void setBodyId(String bodyId) {
this.bodyId = bodyId;
}
public static void main(String[] args){
NutritionFacts nutritionFacts=new NutritionFacts();
nutritionFacts.setAddress("五街");
nutritionFacts.setAge(25);
nutritionFacts.setBodyId("1423423432");
nutritionFacts.setFat(32);
nutritionFacts.setName("小米");
nutritionFacts.setScore(20);
nutritionFacts.setServings(2);
nutritionFacts.setServingSize(43);
nutritionFacts.setSex("男");
}
}
上述的JavaBeans模式有严重的缺点,因为构造过程被分到了几个调用中,而且调试起来很困难,javaBeans阻止了把类做成不可变的可能,需要程序员自己来努力确保线程安全。
最后我们可以使用第三种方法:Build构建器模式,不直接生成想要的对象,而是让客户端利用所有的必要的参数调用构造器没得到一个build对象。然后客户端在Build对象上调用类似于setter的方法,来设置每一个相关的可选参数,然后客户端调用无惨的build方法来生成不可变对象,代码如下
public class NutritionFacts {
private int servingSize = 1;
private int servings = 0;
private int fat = 0;
private int age = 0;
private String name;
private String sex;
public static class Build{
private int servingSize = 1;
private int servings = 0;
private int fat = 0;
private int age = 0;
private String name;
private String sex;
public Build(){}
public Build servingSize(int servingSize){
servingSize=servingSize;
return this;
}
public Build servings(int servings){
servings=servings;
return this;
}
public Build fat(int fat){
fat=fat;
return this;
}
public Build age(int age){
age=age;
return this;
}
public Build name(String name){
name=name;
return this;
}
public Build sex(String sex){
sex=sex;
return this;
}
public NutritionFacts build(){
return new NutritionFacts(this);
}
}
private NutritionFacts(Build build){
servingSize=build.servingSize;
servings=build.servings;
fat=build.fat;
age=build.age;
name=build.name;
sex=build.sex;
}
public static void main(String[] args){
NutritionFacts nutritionFacts=new NutritionFacts.Build().servingSize(10).servings(20).age(25).fat(10).name("小米").sex("男").build()
}
}
如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Build模式就是中不错的选择