Builder设计模式
总结起来,Builder设计模式主要用来解决如下两类问题:
1、多参数对象的构造
2、对象构建和显示分离
为了理解“多参数对象的构造”,请看下面代码:
public class Person
{
private final String lastName;
private final String firstName;
private final String middleName;
private final String salutation;
private final String suffix;
private final String streetAddress;
private final String city;
private final String state;
private final boolean isFemale;
private final boolean isEmployed;
private final boolean isHomewOwner;
public Person(
final String newLastName,
final String newFirstName,
final String newMiddleName,
final String newSalutation,
final String newSuffix,
final String newStreetAddress,
final String newCity,
final String newState,
final boolean newIsFemale,
final boolean newIsEmployed,
final boolean newIsHomeOwner)
{
this.lastName = newLastName;
this.firstName = newFirstName;
this.middleName = newMiddleName;
this.salutation = newSalutation;
this.suffix = newSuffix;
this.streetAddress = newStreetAddress;
this.city = newCity;
this.state = newState;
this.isFemale = newIsFemale;
this.isEmployed = newIsEmployed;
this.isHomewOwner = newIsHomeOwner;
}
}
代码中参数过多,代码不美观。如果需要不同属性组合的构造方法,这里就需要写好多的构造方法,这很明显是不科学的。
下面请看一个Builder模式例子:
class Cake {
private final double sugar; //cup
private final double butter; //cup
private final int eggs;
private final int vanila; //spoon
private final double flour; //cup
private final double bakingpowder; //spoon
private final double milk; //cup
private final int cherry;
public static class Builder {
private double sugar; //cup
private double butter; //cup
private int eggs;
private int vanila; //spoon
private double flour; //cup
private double bakingpowder; //spoon
private double milk; //cup
private int cherry;
//builder methods for setting property
public Builder sugar(double cup){this.sugar = cup; return this; }
public Builder butter(double cup){this.butter = cup; return this; }
public Builder eggs(int number){this.eggs = number; return this; }
public Builder vanila(int spoon){this.vanila = spoon; return this; }
public Builder flour(double cup){this.flour = cup; return this; }
public Builder bakingpowder(double spoon){this.sugar = spoon; return this; }
public Builder milk(double cup){this.milk = cup; return this; }
public Builder cherry(int number){this.cherry = number; return this; }
//return fully build object
public Cake build() {
return new Cake(this);
}
}
private Cake(Builder builder) {
this.sugar = builder.sugar;
this.butter = builder.butter;
this.eggs = builder.eggs;
this.vanila = builder.vanila;
this.flour = builder.flour;
this.bakingpowder = builder.bakingpowder;
this.milk = builder.milk;
this.cherry = builder.cherry;
}
public static void main(String args[]) {
Cake whiteCake = new Cake.Builder().sugar(1).butter(0.5). eggs(2).vanila(2).flour(1.5). bakingpowder(0.75).milk(0.5).build();
}
Builder模式很好的解决了这个问题。
下面再来看看Builder模式用来解决构造和显示分离的情况,直接上代码:
/* "Product" */
class Pizza {
private String dough = "";
private String sauce = "";
private String topping = "";
public void setDough(String dough) { this.dough = dough; }
public void setSauce(String sauce) { this.sauce = sauce; }
public void setTopping(String topping) { this.topping = topping; }
}
/* "Abstract Builder" */
abstract class PizzaBuilder {
protected Pizza pizza;
public Pizza getPizza() { return pizza; }
public void createNewPizzaProduct() { pizza = new Pizza(); }
public abstract void buildDough();
public abstract void buildSauce();
public abstract void buildTopping();
}
/* "ConcreteBuilder" */
class HawaiianPizzaBuilder extends PizzaBuilder {
public void buildDough() { pizza.setDough("cross"); }
public void buildSauce() { pizza.setSauce("mild"); }
public void buildTopping() { pizza.setTopping("ham+pineapple"); }
}
/* "ConcreteBuilder" */
class SpicyPizzaBuilder extends PizzaBuilder {
public void buildDough() { pizza.setDough("pan baked"); }
public void buildSauce() { pizza.setSauce("hot"); }
public void buildTopping() { pizza.setTopping("pepperoni+salami"); }
}
/* "Director" */
class Waiter {
private PizzaBuilder pizzaBuilder;
public void setPizzaBuilder(PizzaBuilder pb) { pizzaBuilder = pb; }
public Pizza getPizza() { return pizzaBuilder.getPizza(); }
public void constructPizza() {
pizzaBuilder.createNewPizzaProduct();
pizzaBuilder.buildDough();
pizzaBuilder.buildSauce();
pizzaBuilder.buildTopping();
}
}
/* A customer ordering a pizza. */
class BuilderExample {
public static void main(String[] args) {
Waiter waiter = new Waiter();
PizzaBuilder hawaiian_pizzabuilder = new HawaiianPizzaBuilder();
PizzaBuilder spicy_pizzabuilder = new SpicyPizzaBuilder();
waiter.setPizzaBuilder( hawaiian_pizzabuilder );
waiter.constructPizza();
Pizza pizza = waiter.getPizza();
}
}
Pizza的制作在PizzaBuilder中,Pizza接口只定义了Pizza的原料。将配方和加工分离,不仅代码精简优美,而且也易于扩展维护。