目錄
1. 介紹
1.1 定義
將一個複雜對象的構建與它的表示分離,使得同樣的構建過程可以創建不同的表示
1.2 主要作用
在用戶不知道對象的建造過程和細節的情況下就可以直接創建複雜的對象。
用戶只需要給出指定複雜對象的類型和內容; 建造者模式負責按順序創建複雜對象(把內部的建造過程和細節隱藏起來)
1.3 解決的問題
方便用戶創建複雜的對象(不需要知道實現過程) 代碼複用性 & 封裝性(將對象構建過程和細節進行封裝 & 複用) 例子:造汽車 & 買汽車。
- 工廠(建造者模式):負責製造汽車(組裝過程和細節在工廠內)
- 汽車購買者(用戶):你只需要說出你需要的型號(對象的類型和內容),然後直接購買就可以使用了 (不需要知道汽車是怎麼組裝的(車輪、車門、發動機、方向盤等等))
2. 模式原理
2.1 UML類圖 & 組成
模式講解:
- 指揮者(Director)直接和客戶(Client)進行需求溝通;
- 溝通後指揮者將客戶創建產品的需求劃分爲各個部件的建造請求(Builder);
- 將各個部件的建造請求委派到具體的建造者(ConcreteBuilder);
- 各個具體建造者負責進行產品部件的構建;
- 最終構建成具體產品(Product)。
2.2 實例講解
接下來我用一個實例來對建造者模式進行更深一步的介紹。
a. 實例概況
背景:小成希望去電腦城買一臺組裝的臺式主機 過程: 電腦城老闆(Diretor)和小成(Client)進行需求溝通(買來打遊戲?學習?看片?) 瞭解需求後,電腦城老闆將小成需要的主機劃分爲各個部件(Builder)的建造請求(CPU、主板blabla) 指揮裝機人員(ConcreteBuilder)去構建組件; 將組件組裝起來成小成需要的電腦(Product)
b. 使用步驟
步驟1: 定義組裝的過程(Builder):組裝電腦的過程
public abstract class Builder { //第一步:裝CPU //聲明爲抽象方法,具體由子類實現 public abstract void BuildCPU(); //第二步:裝主板 //聲明爲抽象方法,具體由子類實現 public abstract void BuildMainboard(); //第三步:裝硬盤 //聲明爲抽象方法,具體由子類實現 public abstract void BuildHD(); //返回產品的方法:獲得組裝好的電腦 public abstract Computer GetComputer(); }
步驟2: 電腦城老闆委派任務給裝機人員(Director)
public class Director{ //指揮裝機人員組裝電腦 public void Construct(Builder builder){ builder. BuildCPU(); builder.BuildMainboard(); builder. BuildHD(); } }
步驟3: 創建具體的建造者(ConcreteBuilder):裝機人員
//裝機人員1 public class ConcreteBuilder extend Builder{ //創建產品實例 Computer computer = new Computer(); //組裝產品 @Override public void BuildCPU(){ computer.Add("組裝CPU") } @Override public void BuildMainboard(){ computer.Add("組裝主板") } @Override public void BuildHD(){ computer.Add("組裝主板") } //返回組裝成功的電腦 @Override public Computer GetComputer(){ return computer } }
步驟4: 定義具體產品類(Product):電腦
public class Computer{ //電腦組件的集合 private List<String> parts = new ArrayList<String>(); //用於將組件組裝到電腦裏 public void Add(String part){ parts.add(part); } public void Show(){ for (int i = 0;i<parts.size();i++){ System.out.println(“組件”+parts.get(i)+“裝好了”); } System.out.println(“電腦組裝完成,請驗收”); } }
步驟5: 客戶端調用-小成到電腦城找老闆買電腦
public class Builder Pattern{ public static void main(String[] args){ //逛了很久終於發現一家合適的電腦店 //找到該店的老闆和裝機人員 Director director = new Director(); Builder builder = new ConcreteBuilder(); //溝通需求後,老闆叫裝機人員去裝電腦 director.Construct(builder); //裝完後,組裝人員搬來組裝好的電腦 Computer computer = builder.GetComputer(); //組裝人員展示電腦給小成看 computer.Show(); } }
結果輸出
組件CUP裝好了 組件主板裝好了 組件硬盤裝好了 電腦組裝完成,請驗收
通過上述這個常見的生活例子,我相信你已經完全明白了建造者模式的原理了!!
3. 優缺點
在全面解析完後,我來分析下其優缺點:
3.1 優點
易於解耦 將產品本身與產品創建過程進行解耦,可以使用相同的創建過程來得到不同的產品。也就說細節依賴抽象。 易於精確控制對象的創建 將複雜產品的創建步驟分解在不同的方法中,使得創建過程更加清晰 易於拓展 增加新的具體建造者無需修改原有類庫的代碼,易於拓展,符合“開閉原則“。 每一個具體建造者都相對獨立,而與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者,用戶使用不同的具體建造者即可得到不同的產品對象。
3.2 缺點
建造者模式所創建的產品一般具有較多的共同點,其組成部分相似;如果產品之間的差異性很大,則不適合使用建造者模式,因此其使用範圍受到一定的限制。 如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大。
4. 應用場景
需要生成的產品對象有複雜的內部結構,這些產品對象具備共性; 隔離複雜對象的創建和使用,並使得相同的創建過程可以創建不同的產品。