定義:
建造者模式(Builder Pattern)也叫做生成器模式,是將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示。簡單的說就是對於複雜對象或者方法的調用邏輯的封裝交易給建造者處理,客戶端調用只需要提供調用要求,而不是考慮實現細節。
基本模型:
從類圖中可以看出基本的建造者模式共有四個角色。:
Product 產品類:包含產品信息
Builder 抽象建造者類:抽取建造者類公共方法
ConcreteBuilder 實際建造者類:實現Builder的方法,返回一個組件好的對象
Director 導演類: 負責安排已有模塊的順序,然後告訴Builder開始建造,在上面的例子中就是我們的老大,××公司找到老大,說我要這個或那個類型的車輛模型,然後老大就把命令傳遞給我,我和我的團隊就開始拼命地建造,於是一個項目建設完畢了。
舉例說明:
需求:小明爲了感謝幫調bug的大熊去咖啡店幫同事買咖啡,小明想喝美式,大熊要喝拿鐵。
設計思路:美式和拿鐵都是咖啡是產品類,咖啡機最終調製咖啡也就是建設者,不過店員是來控制是不不加糖,加奶,所以是導演類。
最終實現:
package com.builder;
import java.util.List;
/**
* 咖啡
*/
public class Coffee {
private void addMike() {
System.out.println("加牛奶");
}
private void addSugar() {
System.out.println("加糖");
}
private void addIce() {
System.out.println("加冰");
}
private void groundCoffeeBean() {
System.out.println("加研磨好的咖啡");
}
private void addWater() {
System.out.println("沖水");
}
//咖啡的組成
public void part(List<String> list) {
for (int i = 0; i < list.size(); i++) {
if ("加研磨好的咖啡".endsWith(list.get(i))) {
this.groundCoffeeBean();
} else if ("沖水".endsWith(list.get(i))) {
this.addWater();
} else if ("加牛奶".endsWith(list.get(i))) {
this.addMike();
} else if ("加糖".endsWith(list.get(i))) {
this.addSugar();
} else if ("加冰".endsWith(list.get(i))) {
this.addIce();
}
}
}
}
package com.builder;
import java.util.List;
/**
* 咖啡機
*/
public abstract class CoffeeMachine {
//製作咖啡
public abstract Coffee makeCoffee(List<String> sequence);
}
package com.builder;
import java.util.List;
/**
* 智能咖啡機
*/
public class AiCoffeeMachine extends CoffeeMachine{
private Coffee coffee = new Coffee();
@Override
public Coffee makeCoffee(List<String> sequence) {
coffee.part(sequence);
return coffee;
}
}
package com.builder;
import java.util.ArrayList;
import java.util.List;
/**
* 店員
* Director類
*/
public class Clerk {
private List<String> list = null;
private AiCoffeeMachine ac = new AiCoffeeMachine();
/**
* 製作冰美式
* @return
*/
public Coffee getCafeAmericano(){
System.out.println("開始製作冰美式----");
list = new ArrayList<>();
list.add("加研磨好的咖啡");
list.add("沖水");
list.add("加冰");
Coffee coffee = ac.makeCoffee(list);
System.out.println("冰美式製作完成----");
return coffee;
}
/**
* 製作拿鐵
* @return
*/
public Coffee getLatte(){
System.out.println("開始製作拿鐵----");
list = new ArrayList<>();
list.add("加研磨好的咖啡");
list.add("沖水");
list.add("加牛奶");
list.add("加糖");
Coffee coffee = ac.makeCoffee(list);
System.out.println("拿鐵製作完成----");
return coffee;
}
}
package com.builder;
public class Test {
public static void main(String[] args) {
Clerk clerk = new Clerk();
clerk.getCafeAmericano();
clerk.getLatte();
}
}
打印結構:
開始製作冰美式----
加研磨好的咖啡
沖水
加冰
冰美式製作完成----
開始製作拿鐵----
加研磨好的咖啡
沖水
加牛奶
加糖
拿鐵製作完成----
總結:
建造者模式的優點:
封裝性良好,客戶端的調用並不關心具體實現細節
易於擴展,建造者是獨立的,如果哪天需要生產奶茶,那擴展一個奶茶建造者。
與模板方法模式和工廠模式:
與模板方法模式:在商品角色中可以與模板方法模式配合使用,建造者模式更關注對象的具體實現細節
與工廠模式:兩種模式的關注點和職責不一致,工廠模式的職則是生產對象,並不關係零件的組裝順序,而建造者模式關注的零件的組裝順序,零件的組裝順序不同,生成的對象可能也不同。