創建模式 -- 建造者模式

来源:https://www.cnblogs.com/l-y-h/archive/2019/08/15/11360427.html
-Advertisement-
Play Games

一、小案例分析 1、功能需求: 現需要建房子,建房流程:挖地基、砌牆、封頂。對於不同種類的房子(高樓,別墅),流程雖然一樣,但是具體功能實現不同。如何實現建房子? 2、小菜雞的答案: (1)定義一個抽象介面,並定義三個抽象方法(挖地基、砌牆、封頂)。(2)對於不同種類的房子,實現該介面,並重寫相關方 ...


一、小案例分析

1、功能需求:

  現需要建房子,建房流程:挖地基、砌牆、封頂。對於不同種類的房子(高樓,別墅),流程雖然一樣,但是具體功能實現不同。如何實現建房子?

2、小菜雞的答案:

(1)定義一個抽象介面,並定義三個抽象方法(挖地基、砌牆、封頂)。
(2)對於不同種類的房子,實現該介面,並重寫相關方法即可。
(3)代碼實現:

package builder.pattern;

/**
 * 測試類
 *
 */
public class BuilderDemo {
    public static void main(String[] args) {
        System.out.println("建別墅流程:");
        BuilderHouse villa = new Villa();

        System.out.println("\n建高樓流程");
        BuilderHouse highBuild = new HighBuild();
    }
}

/**
 * 定義一個建房子的介面,並定義其流程
 */
interface BuilderHouse {
    void scoopHole(); // 挖地基

    void buildWall(); // 砌牆

    void topOff(); // 封頂
}

/**
 * 建別墅,實現建房子的介面
 *
 */
class Villa implements BuilderHouse {
    /**
     * 建別墅流程
     */
    public Villa() {
        scoopHole();
        buildWall();
        topOff();
    }

    @Override
    public void scoopHole() {
        System.out.println("挖10米地基");
    }

    @Override
    public void buildWall() {
        System.out.println("砌10層牆");
    }

    @Override
    public void topOff() {
        System.out.println("樓頂建個游泳池");
    }
}

/**
 * 建高樓流程,實現建房子的介面
 *
 */
class HighBuild implements BuilderHouse {
    /**
     * 建高樓流程
     */
    public HighBuild() {
        scoopHole();
        buildWall();
        topOff();
    }

    @Override
    public void scoopHole() {
        System.out.println("挖30米地基");
    }

    @Override
    public void buildWall() {
        System.out.println("砌60層牆");
    }

    @Override
    public void topOff() {
        System.out.println("樓頂建個停機坪");
    }
}

(4)代碼分析:
  容易理解並操作,但是程式的擴展性不好,且耦合性強(將產品與創建產品的過程封裝在一起)。
(5)UML圖

 

二、建造者模式

1、什麼是建造者模式

  又叫生成器模式,其將複雜的對象的建造過程抽象出來,併在其子類中去實現不同的建造。用戶只需要去調用就行,不需要管建造的內部細節如何實現。簡單的理解為,將一堆零件拼成一個整體,而零件是抽象的,並由不同的子類去實現,用戶不需要管零件是如何形成的,能組裝就行。

2、建造者模式的核心角色

(1)產品(Product):一個具體的產品對象。
(2)抽象建造者(Builder):定義一個介面或抽象類,內部定義生成產品各個零件的抽象方法。
(3)具體建造者(ConcreateBuilder):實現介面,並重寫生成各零件的方法。
(4)組裝者(Commander):按照流程拼接零件,並返回一個對象。
(5)代碼實現:

package builder.pattern;

/**
 * 測試類
 *
 */
public class BuilderDemo {
    public static void main(String[] args) {
        System.out.println("建別墅流程:");
        HouseBuilder villaBuilder = new VillaBuilder();
        HouseCommandar villaCommandar = new HouseCommandar(villaBuilder);
        System.out.println(villaCommandar.createHouse());

        System.out.println("\n建高樓流程");
        HouseBuilder highBuildBuilder = new HighBuildBuilder();
        HouseCommandar highBuildCommandar = new HouseCommandar(highBuildBuilder);
        System.out.println(highBuildCommandar.createHouse());
    }
}

/**
 * 產品類
 *
 */
class House {
    private String basis;
    private String wall;
    private String roof;

    public String getBasis() {
        return basis;
    }

    public void setBasis(String basis) {
        this.basis = basis;
    }

    public String getWall() {
        return wall;
    }

    public void setWall(String wall) {
        this.wall = wall;
    }

    public String getRoof() {
        return roof;
    }

    public void setRoof(String roof) {
        this.roof = roof;
    }

    @Override
    public String toString() {
        return "House [basis=" + basis + ", wall=" + wall + ", roof=" + roof + "]";
    }
}

/**
 * 抽象建造者,內部定義生成產品各個零件的抽象方法。
 *
 */
abstract class HouseBuilder {
    House house = new House();

    public abstract void scoopHole(); // 挖地基

    public abstract void buildWall(); // 砌牆

    public abstract void topOff(); // 封頂

    public House getHouse() {
        return house;
    }
}

/**
 * 具體建造者,建別墅,繼承抽象類,並重寫相關方法
 *
 */
class VillaBuilder extends HouseBuilder {
    @Override
    public void scoopHole() {
        house.setBasis("挖10米地基");
    }

    @Override
    public void buildWall() {
        house.setWall("砌10層牆");
    }

    @Override
    public void topOff() {
        house.setRoof("樓頂建個游泳池");
    }
}

/**
 * 建高樓流程,實現建房子的介面
 *
 */
class HighBuildBuilder extends HouseBuilder {

    @Override
    public void scoopHole() {
        house.setBasis("挖30米地基");
    }

    @Override
    public void buildWall() {
        house.setWall("砌60層牆");
    }

    @Override
    public void topOff() {
        house.setRoof("樓頂建個停機坪");
    }
}

/**
 * 組裝者,控制零件組合流程,並返回一個產品對象
 */
class HouseCommandar {
    private HouseBuilder houseBuilder;

    /**
     * 獲取具體的建造者
     */
    public HouseCommandar(HouseBuilder houseBuilder) {
        this.houseBuilder = houseBuilder;
    }

    /**
     * 控制建房流程,並返回一個房子實例
     * 
     * @return 房子實例
     */
    public House createHouse() {
        houseBuilder.scoopHole();
        houseBuilder.buildWall();
        houseBuilder.topOff();
        return houseBuilder.getHouse();
    }
}

(6)代碼分析:
  相比於上例,其將控制產品流程的代碼抽出來了。使產品與產品構建流程分離,從而在一定程度上解耦。當擴展代碼時,只需繼承HouseBuilder 並重寫相關方法即可。
(7)UML圖:

3、抽象工廠模式與建造者模式的區別

(1)抽象工廠模式是根據不同的工廠去創建一個對象。
(2)建造者模式是根據流程去組裝一個對象。


三、JDK源碼分析(StringBuilder)

1、部分源碼

public final class StringBuilder extends AbstractStringBuilder implements java.io.Serializable, CharSequence{
    
}

abstract class AbstractStringBuilder implements Appendable, CharSequence{
    //內部定義了一系列方法,且部分方法返回值類型為AbstractStringBuilder 
    public AbstractStringBuilder append(String str) {
        if (str == null)
            return appendNull();
        int len = str.length();
        ensureCapacityInternal(count + len);
        str.getChars(0, len, value, count);
        count += len;
        return this;
    }
     public AbstractStringBuilder deleteCharAt(int index) {
        if ((index < 0) || (index >= count))
            throw new StringIndexOutOfBoundsException(index);
        System.arraycopy(value, index+1, value, index, count-index-1);
        count--;
        return this;
    }
} 

2、源碼分析

  AbstractStringBuilder 內部定義了一系列返回值類型為AbstractStringBuilder 的方法,這些方法可以組合起來,形成鏈式調用(產品構建流程),根據鏈式調用來組裝成最後返回的對象。
即StringBuilder 是組裝者與具體建造者。AbstractStringBuilder 是抽象建造者。
  


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • meta元素有4個屬性:name、http-equiv、content、charset.meta標簽通過name屬性來表述頁面文檔的元信息,通過http-equiv屬性設置http請求指令,通過charset設置頁面的字元編碼。按照屬性設置分類,meta可以分為三類: name屬性和content屬 ...
  • 1. 什麼是對象? 對象object 是一些相關的變數和方法的軟體集。 特性: 屬性和方法 JavaScript中的所有事物都是對象。 創建對象的方法: 建立一個工廠函數 2.什麼是面向對象? 面向對象是一個思想,就是把解決問題的註意力集中到對象上。 面向對象的三大特點:封裝 繼承 多態。 封裝:把 ...
  • 前端項目優化 -Web 開發常用優化方案、Vue & React 項目優化 ...
  • 01. JavaScript的運行機制 (1)所有同步任務都在主線程上執行,形成一個執行棧。(2)主線程之外,還有一個“任務隊列”,只要非同步任務有了運行結果,就在“任務隊列”之中放置一個事件。(3)一旦“執行棧”中的所有同步任務執行完畢了,系統就會讀取“任務隊列”,看看裡面有哪些事件。那些對應的非同步 ...
  • 前言 今天沒有什麼前言,就是想分享些關於 的技術,任性。來吧,各位客官,裡邊請... 開篇第一問: 是什麼嘞? 首先咱們說哈,爬蟲不是“蟲子”,姑涼們不要害怕。 一種通過一定方式按照一定規則抓取數據的操作或方法。 開篇第二問: 能做什麼嘞? 來來來,談談需求 產品MM: 1. 愛豆的新電影上架了,整 ...
  • 微服務與K8S容器雲平臺架構微服務與12要素網路日誌收集服務網關服務註冊服務治理- java agent監控今天先到這兒,希望對技術領導力, 企業管理,系統架構設計與評估,團隊管理, 項目管理, 產品管理,團隊建設 有參考作用 , 您可能感興趣的文章: 領導人怎樣帶領好團隊構建創業公司突擊小團隊國際... ...
  • 優雅的在WinForm/WPF/控制台 中使用特性封裝WebApi 說明 ` 在C/S端作為Server,建立HTTP請求,方便快捷。 ` 1.使用到的類庫 ` Newtonsoft.dll ` 2.封裝 HttpListener HttpApi類 特性類 ActionName 特性類 HttpMe ...
  • 簡單工廠模式 簡單工廠模式不是 23 種里的一種,簡而言之,就是有一個專門生產某個產品的類。 比如下圖中的滑鼠工廠,專業生產滑鼠,給參數 0,生產戴爾滑鼠,給參數 1,生產惠普滑鼠。 工廠模式 工廠模式也就是滑鼠工廠是個父類,有生產滑鼠這個介面。 戴爾滑鼠工廠,惠普滑鼠工廠繼承它,可以分別生產戴爾鼠 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...