ivaneye.com

语言与模式-05生成器模式

意图

将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

适用性

Java实现

// 待构建产品
class Starbucks {
    private String size;
    private String drink;
    public void setSize(String size) {
        this.size = size;
    }
    public void setDrink(String drink) {
        this.drink = drink;
    }
}
//抽象builder
abstract class StarbucksBuilder {
    protected Starbucks starbucks;
    public Starbucks getStarbucks() {
        return starbucks;
    }
    public void createStarbucks() {
        starbucks = new Starbucks();
        System.out.println("a drink is created");
    }
    public abstract void buildSize();
    public abstract void buildDrink();
}
// 泡茶builder
class TeaBuilder extends StarbucksBuilder {
    public void buildSize() {
        starbucks.setSize("large");
        System.out.println("build large size");
    }
    public void buildDrink() {
        starbucks.setDrink("tea");
        System.out.println("build tea");
    }
}
// 泡咖啡builder
class CoffeeBuilder extends StarbucksBuilder {
    public void buildSize() {
        starbucks.setSize("medium");
        System.out.println("build medium size");
    }
    public void buildDrink() {
        starbucks.setDrink("coffee");
        System.out.println("build coffee");
    }
}
//指导如何封装builder
class Waiter {
    private StarbucksBuilder starbucksBuilder;
    public void setStarbucksBuilder(StarbucksBuilder builder) {
        starbucksBuilder = builder;
    }
    public Starbucks getstarbucksDrink() {
        return starbucksBuilder.getStarbucks();
    }
    public void constructStarbucks() {
        starbucksBuilder.createStarbucks();
        starbucksBuilder.buildDrink();
        starbucksBuilder.buildSize();
    }
}
//客户
public class Customer {
    public static void main(String[] args) {
        Waiter waiter = new Waiter();
        StarbucksBuilder coffeeBuilder = new CoffeeBuilder();
        //也可以用泡茶builder沏茶
        //StarbucksBuilder teaBuilder = new TeaBuilder();
        waiter.setStarbucksBuilder(coffeeBuilder);
        waiter.constructStarbucks();
        //取到饮料
        Starbucks drink = waiter.getstarbucksDrink();
    }
}

Clojure实现

在Clojure里也是个没必要的模式!因为根本就不需要构建对象啊!

可以使用multimethod模拟,或者直接简单模拟如下:

(defn type [d t]
  (assoc d :type t))
(defn size [d t]
  (assoc d :size t))
(def drink {})
(-> drink (type :tea) (size :large))