意圖
將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。
適用性
- 當創建複雜對象的算法應該獨立於該對象的組成部分以及它們的裝配方式時。
- 當構造過程必須允許被構造的對象有不同的表示時。
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))
“`