建造者模式
-
建造者模式也屬于創建型模式,它提供了一種創建對象的最佳方式
-
定義:將一個復雜對象的構建和它的表示分離,使得同樣的構建過程可以創建不同的表示(假設有不同的建造者實現類,可以產生不同的產品)
-
主要作用:在用戶不知道對象的創建過程和細節的情況下(用戶只需要調指揮者來創建就可以了)就可以直接創建復雜的對象。
-
用戶只需要給出指定復雜對象的類型和內容,建造者負責按順序創建復雜對象(把內部的建造過程和細節隱藏起來)
-
例子:
-
工廠(建造者模式):負責制造汽車(組裝過程和細節在工廠內)
-
汽車購買者(用戶):你只要說出你需要的型號(對象的類型與內容),然后可以直接購買就可以使用了(雖然不知道汽車怎么組裝的(車輪、車門、發動機、方向盤等等))
-
-
角色分析:
-
既然是建造者模式,那么我們還是繼續就以造房子為例子,假設將造房簡化為以下步驟:
-
地基
-
鋼筋工程
-
鋪電線
-
粉刷
-
如果要蓋一間房子,首先是要一個建筑公司或工程承包商(指揮者),承包商指揮工人(具體建造者)來造房子(產品),最后驗收
代碼展示:
首先先創建抽象建造者
package com.lyc.builder.demo01;
//抽象的建造者,只負責定義一些接口與方法
public abstract class Builder {public abstract void buildPartA();public abstract void buildPartB();public abstract void buildPartC();public abstract void buildPartD();//完工:得到產品public abstract Product getResult();
}
再創建產品類
package com.lyc.builder.demo01;import lombok.Data;//產品:房子
@Data
public class Product {private String partA;private String partB;private String partC;private String partD;
}
再創建具體建造者實現類
package com.lyc.builder.demo01;
//具體的建造者 worker是builder的具體實現,一個builder可能有幾個不同的worker
public class Worker extends Builder{private Product product;public Worker(){product = new Product();}@Overridepublic void buildPartA() {product.setPartA("partA");System.out.println("partA");}@Overridepublic void buildPartB() {product.setPartB("partB");System.out.println("partB");}@Overridepublic void buildPartC() {product.setPartC("partC");System.out.println("partC");}@Overridepublic void buildPartD() {product.setPartD("partD");System.out.println("partD");}@Overridepublic Product getResult() {return product;}
}
在創建指揮類Director
package com.lyc.builder.demo01;
//指揮者 核心,負責指揮構建一個工程,工程如何構建,有他決定
public class Director {//指揮工人按照順序建造房子public Product builder(Builder builder){//指揮者可以指揮工人按照不同的順序執行方法,builder.buildPartA();builder.buildPartB();builder.buildPartC();builder.buildPartD();//返回產品return builder.getResult();}
}
最后進行測試
public class Test {public static void main(String[] args) {//指揮Director director = new Director();Product builder = director.builder(new Worker());System.out.println(builder.toString());}
}
細節分析:
-
上面示例是Builder模式的常規用法,導演Director在Builder模式中具有重要的作用,它用于指導具體構建者如何構建產品,控制調用先后次序,并向調用者返回完整的產品類,但是有些情況下需要簡化系統結構,可以把Director與抽象建造者進行結合
-
通過靜態內部類方式實現零件無序裝配構造,這種方式使用更加靈活,更符合定義,內部有復雜對象的默認實現,使用時可以根據用戶需求自由定義更改內容,并且無需改變具體的構造方式。就可以生產出不同復雜的產品
-
比如:漢堡套餐,服務員(具體建造者)可以隨意搭配任意幾種產品組成一款套餐(產品),比第一種少了Director,主要是因為第二種方式把指揮者交給用戶操作,使得產品創建更加簡單靈活
第二種方式代碼展示:
首先還是需要創建抽象建造類
public abstract class Builder {public abstract Builder buildPartA(String msg); //漢堡public abstract Builder buildPartB(String msg); //可樂public abstract Builder buildPartC(String msg); //薯條public abstract Builder buildPartD(String msg); //甜品// 返回產品public abstract Product getResult();
}
創建產品類(這里存放著默認的產品)
import lombok.Data;//產品:套餐
@Data
public class Product {//默認套餐private String partA = "漢堡";private String partB = "可樂";private String partC = "薯條";private String partD = "甜點";
}
具體的創建者實現類
package com.lyc.builder.demo02;
//具體建造者
public class Worker extends Builder{private Product product;public Worker(){product = new Product();}@Overridepublic Builder buildPartA(String msg) {product.setPartA(msg);return this;}@Overridepublic Builder buildPartB(String msg) {product.setPartB(msg);return this;}@Overridepublic Builder buildPartC(String msg) {product.setPartC(msg);return this;}@Overridepublic Builder buildPartD(String msg) {product.setPartD(msg);return this;}@Overridepublic Product getResult() {return product;}
}
最后進行測試
package com.lyc.builder.demo02;public class Test {public static void main(String[] args) {//服務員Worker worker = new Worker();//鏈式編程 :在原來的基礎上,可以自由組合,如果不組合,也有默認的套餐Product result = worker.buildPartA("全家桶").buildPartB("雪碧").getResult();System.out.println(result.toString());}
}
這里將指揮者與客戶端相結合,讓客戶端自己來進行套餐的搭配。
建造者模式與工廠模式的區別:
工廠模式是造什么,建造者模式是怎么造,一個宏觀,一個微觀
建造者模式優點:
-
產品的建造與表示分離,實現了解耦,使用建造者模式可以使客戶端不必知道產品內部組成的細節。
-
將復雜的產品的創建步驟分解在不同的方法中,使得創建過程更加清晰
-
具體的建造者類之間是相互獨立的,這有利于系統的擴展,增加新的具體建造者無需修改原有類庫的代碼,符合“開閉原則”。
缺點:
-
建造者模式所創建的產品一般具有較多的共同點,其組成部分相似;如果產品之間的差異性很大,則不適合使用創造者模式,因此其適用范圍受到了一定的限制。
-
如果產品的內部變化復雜,可能會導致需要定義很多具體建造者來實現這種變化,導致系統變得很龐大
應用場景:
-
需要生成的產品對象有復雜的內部結構,這些產品對象具備共性;
-
隔離復雜對象的創建和使用,并使得相同的創建過程可以創建不同的產品。
-
適合于一個具有較多的零件(屬性)的產品(對象)的創建過程。
建造者與抽象工廠模式的比較:
-
與抽象工廠模式相比,建造者模式返回一個組裝好的完整產品,而抽象工廠模式返回一系列相關的產品,這些產品位于不同的產品等級結構,構成了一個產品族。
-
在抽象工廠模式中,客戶端實例化工廠類,然后調用工廠方法獲取所需產品對象,抽象工廠模式側重于直接通過工廠制造獲得對象 而在建造者模式中客戶端可以不直接調用建造者的相關方法,而是通過指揮者類來指導如何生成對象,包括對象的組裝過程和建造步驟,它側重于一步步構造一個復雜對象,返回一個完整的對象。
-
如果將抽象工廠模式看成汽車配件生產工廠,生產一個產品族的產品,那么建造者模式就是一個汽車組裝工廠,通過對部件的組裝可以返回一輛完整的汽車!
我們需要清楚的認識到工廠模式與創建者模式的區別,并且勤加練習,希望對大家有所幫助