- 当一个类的参数有很多个的时候,有比较好构建方法
- 比如这个类有四个参数,可以使用几个构造器,其中一个参数的构造器调用两个参数的构造器,两个参数的构造器调用三个参数的构造器,三个的调用四个的,这种方式叫做重叠构造器
package constructors.builder; public class NutritionFacts { private final int servingsSize; private final int servings; private final int calories; private final int fat; private final int sodium; private final int carbohydrate; public static class Builder{ private final int servingSize; private final int servings; private int calories = 0; private int fat = 0; private int sodium = 0; private int carbohydrate = 0; public Builder(int servingSize, int servings){ this.servingSize = servingSize; this.servings = servings; } public Builder calories(int val){ calories = val; return this; } public Builder fat(int val){ fat = val; return this; } public Builder sodium(int val){ sodium = val; return this; } public Builder carbohydrate(int val){ carbohydrate = val; return this; } public NutritionFacts build(){ return new NutritionFacts(this); } } private NutritionFacts(Builder builder){ servingsSize = builder.servingSize; servings = builder.servings; calories = builder.calories; fat = builder.fat; sodium = builder.sodium; carbohydrate = builder.carbohydrate; } }
- 构建者模式
- 在A类里边定义一个静态内部类Builder
- Builder类拥有和A类一样多的成员变量
- 对于必填的成员变量,将其设置在Builder的构造函数中
- 对于不必要的成员变量,通过一些方法设置值,然后返回这个builder变量
- 在Builder类中写builder方法,这个方法创建了一个A类对象,构造器参数是Builder
- A类有一个参数是Builder的构造器,构造器的逻辑是将Builder的各个参数转换成自己的各个参数
package constructors.builder; public class NutritionFacts { private final int servingsSize; private final int servings; private final int calories; private final int fat; private final int sodium; private final int carbohydrate; // Builder 是静态内部类 public static class Builder{ // builder拥有和外部类一样的成员变量 private final int servingSize; private final int servings; private int calories = 0; private int fat = 0; private int sodium = 0; private int carbohydrate = 0; // 必要的参数作为Builder的过构造函数参数 public Builder(int servingSize, int servings){ this.servingSize = servingSize; this.servings = servings; } // 其他参数作为具体的方法进行设置,最后返回builder对象 public Builder calories(int val){ calories = val; return this; } public Builder fat(int val){ fat = val; return this; } public Builder sodium(int val){ sodium = val; return this; } public Builder carbohydrate(int val){ carbohydrate = val; return this; } // builder方法构建一个外部类对象 public NutritionFacts build(){ return new NutritionFacts(this); } } // builder类参数的构造函数,用于参数转化 private NutritionFacts(Builder builder){ servingsSize = builder.servingSize; servings = builder.servings; calories = builder.calories; fat = builder.fat; sodium = builder.sodium; carbohydrate = builder.carbohydrate; } }
- 接下来是一个比较复杂的例子,抽象类结构中的构建者模式
- 父类中维护了一个集合,
- 父类中有一个抽象的Builder类,这个Builder也有一个集合,是用来最后转换为外部类的,并且有向这个集合里添加元素的方法
- 父类的Builder类中还有一个self方法,这个self方法在父类的添加元素中被调用,可以返回子类的builder对象
- 父类的Builder中有builder方法,是抽象类,子类中重写这个方法,返回子类builder对应的外部类类型
package constructors.builder; import java.util.EnumSet; import java.util.Objects; import java.util.Set; public abstract class Pizza { public enum Topping{ HAM,MUSHROOM,ONLON,PRPPER,SAUSAGE } // 父类维护了一个集合 final Set<Topping> toppings; abstract static class Builder<T extends Builder<T>>{ EnumSet<Topping> toppings = EnumSet.noneOf(Topping.class); // 父类的Builder中有向集合添加元素的方法 public T addTopping(Topping topping){ toppings.add(Objects.requireNonNull(topping)); return self(); } // build和self方法是抽象的,留给子类去实现 abstract Pizza build(); protected abstract T self(); } // 转换成员变量构造函数 Pizza(Builder<?> builder){ toppings = builder.toppings.clone(); } }
package constructors.builder; import java.util.Objects; public class NyPizza extends Pizza { public enum Size {SMALL, MEDIUM, LARGE} private final Size size; public static class Builder extends Pizza.Builder<Builder>{ private final Size size; // 子类自己的构造函数,用于子类自己特有成员赋值 public Builder(Size size){ this.size = Objects.requireNonNull(size); } // 这两个重写的方法,都是用于返回自理自己的builder对象和外部类对象 @Override Pizza build() { return new NyPizza(this); } @Override protected Builder self() { return this; } } private NyPizza(Builder builder){ super(builder); size = builder.size; } }
package constructors.builder; public class Calzone extends Pizza { private final boolean sauceInside; // Builder是Pizza的内部类 public static class Builder extends Pizza.Builder<Builder>{ private boolean sauceInside = false; // 子类builder构造函数,用于子类特有成员变量赋值 public Builder sauceInside(){ sauceInside = true; return this; } @Override Pizza build() { sauceInside = true; return new Calzone(this); } @Override protected Builder self() { return this; } } private Calzone(Builder builder){ super(builder); sauceInside = builder.sauceInside; } }
- 比如这个类有四个参数,可以使用几个构造器,其中一个参数的构造器调用两个参数的构造器,两个参数的构造器调用三个参数的构造器,三个的调用四个的,这种方式叫做重叠构造器
effecitve java 2 构建器
最新推荐文章于 2021-10-29 14:32:06 发布