定義:建造者模式也稱為生成器模式,將一個個簡單對象一步步構造成一個複雜的對象,將複雜對象的構建和它的表示分離,使得同樣的構建過程有不同的表示; 主要解決:系統中複雜對象的創建過程,通常由各個部分的子對象採用一定的演算法構成;由於需求的變化 ,這個複雜對象的各個部分通常面臨著劇烈的變化,但是將他們組合在 ...
定義:建造者模式也稱為生成器模式,將一個個簡單對象一步步構造成一個複雜的對象,將複雜對象的構建和它的表示分離,使得同樣的構建過程有不同的表示;
主要解決:系統中複雜對象的創建過程,通常由各個部分的子對象採用一定的演算法構成;由於需求的變化 ,這個複雜對象的各個部分通常面臨著劇烈的變化,但是將他們組合在一起的演算法卻相對穩定;
何時使用:一些基本部件不變,而其組合經常變化的時候;
如何解決:將變與不變相分離;
模式結構(PS:本圖是從網上找過來的):
模式角色分析:
1、產品類:是一個較為複雜的對象,這個對象的創建過程較為複雜,實際編程中可以由一個抽象類和它的不同實現組成,也可以由抽象類與他們的實現組成;
2、抽象建造者:引入抽象建造者的目的,是為了將建造的具體過程交給它的子類來實現,這樣更容易擴展,同時也符合面向介面編程的出發點,一般包含兩個抽象方法,一個用來建造產品,一個用來返回產品;
3、建造者:實現抽象類所有未實現的方法,組件產品,返回組裝好的產品;
4、指揮類:負責調用適當的建造者來組建產品,指揮類一般不與產品類發生依賴關係,與指揮類直接交互的是建造者類,一般來說指揮類被用來封裝程式中易變的部分;
應用場景:
1、創建複雜對象的演算法獨立於組成對象的部件;
2、肯德基的漢堡、可樂、薯條、炸雞等是不變的,而其組合是經常變化的,將不同的產品組合在一起,生成出來所謂的“套餐”;
3、jdk中的StringBuilder類;
4、同一個創建過程需要有不同的內部屬性的產品對象,例如建造房子,利用沙子、水泥、鋼筋既可以建造別墅也可以建造普通樓房;
優點:
1、客戶端不必知道產品組成的細節,將產品本身與產品的創建過程,使得相同的創建過程可以創建不同的產品對象;
2、每個具體建造者都獨立,因此可以方便地更換、或者增加具體的建造者,用戶使用不同的具體建造者可以得到不同的產品對象;
3、可以更精細地控制產品的創建過程,將複雜產品的創建步驟分解在不同的方法中,使得創建過程更加清晰;
4、增加新的具體的建造者不需要修改原來類庫的代碼,指揮類針對抽象建造者類編程,系統方便擴展,符合“開閉原則”;
缺點:
1、建造者過多時,會產生很多類,難以維護;
2、建造者模式所創建的產品一般具有較多的共同點,其組成部分相似,若產品之間的差異性很大,則不適合使用該模式,使用範圍受限;
工廠模式和建造者模式聯繫和區別:
工廠模式重點關註如何獲取實例對象,而建造者模式重點關註如何建造實例對象;建造者模式和工廠模式從總體上看僅僅是多了一個“指揮類”的角色,如果將“指揮類”看做是最終調用的客戶端,那麼剩餘部分就可以看做是一個簡單的工廠模式了,工廠模式是將實例對象的建造過程封裝在工廠中了,工廠直接返回實例對象給調用者,而建造者模式是將實例對象的建造過程封裝在了具體的建造者類中,由“指揮類”調用,返回對象給客戶端調用;
UML類圖:
示例代碼:
package cn.com.pep.model.builder.builder2; /** * * @Title: Builder * @Description: 抽象建造者 * @author wwh * @date 2022-9-1 9:56:08 */ public abstract class Builder { /** * * @Title: builderPartA * @Description: */ public abstract void builderPartA(); /** * * @Title: builderPartB * @Description: */ public abstract void builderPartB(); /** * * @Title: getProduct * @Description: * @return */ public abstract Product getProduct(); }
package cn.com.pep.model.builder.builder2; /** * * @Title: ConcreteBuilderA * @Description: 具體建造者A * @author wwh * @date 2022-9-1 10:00:40 */ public class ConcreteBuilderA extends Builder{ private Product product = new Product(); @Override public void builderPartA() { product.addPart("VegetableBurger"); } @Override public void builderPartB() { product.addPart("Cocacola"); } @Override public Product getProduct() { return product; } }
package cn.com.pep.model.builder.builder2; /** * * @Title: ConcreteBuilderB * @Description: 具體建造者B * @author wwh * @date 2022-9-1 10:04:48 */ public class ConcreteBuilderB extends Builder{ private Product product = new Product(); @Override public void builderPartA() { // TODO Auto-generated method stub product.addPart("ChickenBurger"); } @Override public void builderPartB() { // TODO Auto-generated method stub product.addPart("Pepsi"); } @Override public Product getProduct() { // TODO Auto-generated method stub return product; } }
package cn.com.pep.model.builder.builder2; /** * * @Title: Product * @Description: * @author wwh * @date 2022-9-1 9:50:03 */ import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * * @Title: Product * @Description: 產品類 * @author wwh * @date 2022-9-1 9:55:50 */ public class Product { List<String> parts = new ArrayList<>(); /** * * @Title: addPart * @Description: 添加產品部件 * @param part */ public void addPart(String part) { parts.add(part); } /** * * @Title: show * @Description:顯示產品細節 */ public void show() { Iterator<String> it = parts.iterator(); while (it.hasNext()) { String string = (String) it.next(); System.err.println(string); } } }
package cn.com.pep.model.builder.builder2; /** * * @Title: Director * @Description: 指揮者類 * @author wwh * @date 2022-9-1 10:12:05 */ public class Director { /** * * @Title: creatProduct * @Description: * @param builder */ public void creatProduct(Builder builder) { builder.builderPartA(); builder.builderPartB(); } }
package cn.com.pep.model.builder.builder2; /** * * @Title: BuilderPatternDemo * @Description: 測試類 * @author wwh * @date 2022-9-1 10:13:51 */ public class BuilderPatternDemo { public static void main(String[] args) { Builder builder = new ConcreteBuilderA(); Director director = new Director(); director.creatProduct(builder); Product p = builder.getProduct(); p.show(); builder = new ConcreteBuilderB(); director.creatProduct(builder); p = builder.getProduct(); p.show(); } }
本文來自博客園,作者:一隻烤鴨朝北走,僅用於技術學習,所有資源都來源於網路,部分是轉發,部分是個人總結。歡迎共同學習和轉載,轉載請在醒目位置標明原文。如有侵權,請留言告知,及時撤除。轉載請註明原文鏈接:https://www.cnblogs.com/wha6239/p/16643030.html