先说结论:如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Bulider模式就是一种不错的选择。
首先静态工厂和构造器(重叠构造器)都有一个局限性:它们不能很好的扩展到大量的可选参数。换而言之就是有许多参数时,客户端代码会很难编写,并且仍然难以阅读。
JavaBeans模式的缺点:在构造过程中可能处于不一致的状态。使得把类变成不可变的可能性不复存在,这就需要程序员付出格外努力来确保线程安全。
Bulider模式:既可以保证像重叠构造器的安全性,又可以保证像JavaBeans模式那么好的可续性。
show you the code:
//定义一个抽象类Pizza
public abstract class Pizza {
public enum Topping {HAM,MUSHROOM,ONION,PEPPER,SAUSAGE}
final Set<Topping> toppings;
abstract static class Builder<T extends Builder<T>>{
EnumSet<Topping> toppings = EnumSet.noneOf(Topping.class);
public T addTopping(Topping topping){
toppings.add(Objects.requireNonNull(topping));
return self();
}
abstract Pizza build();
protected abstract T self();
}
Pizza(Builder<?> builder){
toppings = builder.toppings.clone();
}
}
然后有2个子类纽约🍕和馅料🍕各自也实现自己的bulider
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);
}
@Override
Pizza 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<Builder>{
private boolean sauceInside = false;
@Override
Pizza build() {
return new Calzone(this);
}
@Override
protected Builder self() {
return this;
}
}
private Calzone(Builder builder){
super(builder);
sauceInside = builder.sauceInside;
}
}