可伸缩构造方法模式(new对象)是有效的,但是当有很多参数时,很难编写客户端代码,而且很读懂它。
JavaBeans 模式(get/set设置属性)本身有严重的缺陷。由于构造方法被分割成了多次调用,所以在构造程中 JavaBean 可能处于不一致的状态, 并且排除了让类不可变的可能性,不够安全。
Builder 模式结合了可伸缩构造方法模式的安全性和 JavaBean 模式的可读性。客户端不直接构造所需的对象,而是调用一个包含所有必参数的构造方法 (或静态工厂) 得到获得一个 builder 对象。然后,客户端调用 builder 对象的setter 相似的方法来设置你想设置的可选参数。最后,客户端调用 builder 对象的一个无参build 方法来生成对象,该对象通常是不可变的。Builder 通常是它所构建的类的一个静态成员类。
@Builder public class NutritionFacts { private final int servingSize; private final int servings; private final int calories; private final int fat; private final int sodium; private final int carbohydrate; } //客户端代 NutritionFacts nutritionFacts = new NutritionFacts.NutritionFactsBuilder() .calories(1).carbohydrate(2).fat(3).sodium(4) .build();
Builder 模式非常适合类层次结构。 使用平行层次的 builder,每个 builder 嵌套在相应的类中。 抽
象类有抽象的 builder;具体的类有具体的 builder。
示例代码:
public abstract class Pizza { public enum Topping {HAM, HUSHROOM, ONION, PEPPER, SAUSAGE} final Settoppings; abstract static class Builder > { EnumSet toppings = EnumSet.noneOf(Topping.class); public T addTopping(Topping topping) { toppings.add(Objects.requireNonNull(topping)); return this.self(); } abstract Pizza build(); protected abstract T self(); } Pizza(Builder> builder) { toppings = builder.toppings.clone(); } }
public class NyPizza extends Pizza { public enum Size {SMALL, MEDIUM, LARGE} private final Size size; public static class Builder extends Pizza.Builder{ private final Size size; public Builder(Size size) { this.size = Objects.requireNonNull(size); } @Override NyPizza build() { return new NyPizza(this); } @Override protected Builder self() { return this; } } private NyPizza(Builder builder) { super(builder); size = builder.size; } }
public class Calzone extends Pizza { private final boolean sauceInside; public static class Builder extends Pizza.Builder{ private boolean sauceInside = false; public Builder sauceInside() { sauceInside = true; return this; } @Override Calzone build() { return new Calzone(this); } @Override protected Builder self() { return this; } } private Calzone(Builder builder) { super(builder); sauceInside = builder.sauceInside; } }
Pizza build = new NyPizza.Builder(NyPizza.Size.SMALL) .addTopping(Pizza.Topping.HAM) .addTopping(Pizza.Topping.ONION) .build(); Calzone calzone = new Calzone.Builder() .addTopping(Pizza.Topping.HAM).sauceInside().build();
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)