建造者模式 Builder
建造者模式用于创建过程稳定,但配置多变的对象。在《设计模式》一书中的定义是:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
经典的“建造者-指挥者”模式现在已经不太常用了,现在建造者模式主要用来通过链式调用生成不同的配置。比如我们要制作一杯珍珠奶茶。它的制作过程是稳定的,除了必须要知道奶茶的种类和规格外,是否加珍珠和是否加冰是可选的。使用建造者模式表示如下:
public class MilkTea { private final String type; private final String size; private final boolean pearl; private final boolean ice;
private MilkTea() {} private MilkTea(Builder builder) { this.type = builder.type; this.size = builder.size; this.pearl = builder.pearl; this.ice = builder.ice; }
public String getType() { return type; }
public String getSize() { return size; }
public boolean isPearl() { return pearl; } public boolean isIce() { return ice; }
public static class Builder {
private final String type; private String size = "中杯"; private boolean pearl = true; private boolean ice = false;
public Builder(String type) { this.type = type; }
public Builder size(String size) { this.size = size; return this; }
public Builder pearl(boolean pearl) { this.pearl = pearl; return this; }
public Builder ice(boolean cold) { this.ice = cold; return this; }
public MilkTea build() { return new MilkTea(this); } } }
|
可以看到,我们将 MilkTea 的构造方法设置为私有的,所以外部不能通过 new 构建出 MilkTea 实例,只能通过 Builder 构建。对于必须配置的属性,通过 Builder 的构造方法传入,可选的属性通过 Builder 的链式调用方法传入,如果不配置,将使用默认配置,也就是中杯、加珍珠、不加冰。根据不同的配置可以制作出不同的奶茶:
public class User { private void buyMilkTea() { MilkTea milkTea = new MilkTea.Builder("原味").build(); show(milkTea);
MilkTea chocolate =new MilkTea.Builder("巧克力味") .ice(false) .build(); show(chocolate); MilkTea strawberry = new MilkTea.Builder("草莓味") .size("大杯") .pearl(false) .ice(true) .build(); show(strawberry); }
private void show(MilkTea milkTea) { String pearl; if (milkTea.isPearl()) pearl = "加珍珠"; else pearl = "不加珍珠"; String ice; if (milkTea.isIce()) { ice = "加冰"; } else { ice = "不加冰"; } System.out.println("一份" + milkTea.getSize() + "、" + pearl + "、" + ice + "的" + milkTea.getType() + "奶茶"); } }
|
好处
使用建造者模式的好处是不用担心忘了指定某个配置,保证了构建过程是稳定的。在 OkHttp、Retrofit 等著名框架的源码中都使用到了建造者模式。
总结
构造者实际为配置类,是一个静态内部类。用来作为目标类的的构造方法的入参。构造者 在build方法中new 出目标类,其它方法中则设置属性返回this(构造者)以形成配置的链式调用。