如果类的构造器或者静态工厂中具有多个参数,设计这种类时, Builde模式就是一种不错的选择, 特别是当大多数参数都是可选或者类型相同的时候 。 与使用 重叠构造器模式相比,使用 Builder模式 的客户端代码将更 易于 阅读和编写,构建器也比 JavaBeans 更加安全
import java.util.EnumSet;
import java.util.Objects;
import java.util.Set;
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) {
this.toppings = builder.toppings.clone();
}
@Override
public String toString() {
return "Pizza{" +
"toppings=" + toppings +
'}';
}
}
import java.util.Objects;
public class NyPizza extends Pizza {
private final Size size;
public enum Size {SMALL, MEDIUM, LARGE}
private NyPizza(Builder builder) {
super(builder);
size = builder.size;
}
public static class Builder extends Pizza.Builder<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;
}
}
@Override
public String toString() {
return "NyPizza{" +
"size=" + size +
"} " + super.toString();
}
}
public class CalZone extends Pizza {
/**
* 加酱
*/
private final boolean sauceInside;
private CalZone(Builder builder) {
super(builder);
sauceInside = builder.sauceInside;
}
public static class Builder extends Pizza.Builder<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;
}
}
@Override
public String toString() {
return "CalZone{" +
"sauceInside=" + sauceInside +
"} " + super.toString();
}
}
public class CalZone extends Pizza {
/**
* 加酱
*/
private final boolean sauceInside;
private CalZone(Builder builder) {
super(builder);
sauceInside = builder.sauceInside;
}
public static class Builder extends Pizza.Builder<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;
}
}
@Override
public String toString() {
return "CalZone{" +
"sauceInside=" + sauceInside +
"} " + super.toString();
}
}
import org.junit.Test;
import static builder.NyPizza.Size.SMALL;
import static builder.Pizza.Topping.*;
public class BuilderTest {
@Test
public void test(){
NyPizza pizza = new NyPizza.Builder(SMALL)
.addTopping(SAUSAGE)
.addTopping(ONION)
.build();
System.out.println(pizza);
CalZone calZone = new CalZone.Builder()
.addTopping(HAM).sauceInside()
.build();
System.out.println(calZone);
}
}