第二条:遇到多个构造器参数时要考虑用构建器

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

猜你喜欢

转载自blog.csdn.net/qiuhao9527/article/details/80771145