静态工厂和构造器都有一个共同的局限性:他们都不能很好地扩展到大量的可选参数,例如有一个对象,有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模式就是中不错的选择