圖解Java設計模式之建造者模式

来源:https://www.cnblogs.com/haizai/archive/2020/03/09/12447326.html
-Advertisement-
Play Games

圖解Java設計模式之建造者模式 蓋房項目需求 傳統方式解決蓋房需求 傳統方式的問題分析 建造者模式基本介紹 建造者模式的四個角色 建造者模式原理類圖 建造者模式在JDK的應用和源碼分析 建造者模式的註意事項和細節 蓋房項目需求 1)需要建房子 :這一過程為打樁、砌牆、封頂2)房子有各種各樣的,比如 ...


圖解Java設計模式之建造者模式

 

蓋房項目需求

1)需要建房子 :這一過程為打樁、砌牆、封頂
2)房子有各種各樣的,比如普通房、高樓、別墅,各種房子的過程雖然一樣,但是要求不要相同的。

傳統方式解決蓋房需求

1)思路分析(圖解)
在這裡插入圖片描述

package com.example.demo.builder;

public abstract class AbstractHouse {
	
	/**
	 * 打地基
	 */
	public abstract void buildBasic();

	/**
	 * 砌牆
	 */
	public abstract void buildWalls();
	
	/**
	 * 封頂
	 */
	public abstract void roofed();
	
	public void build() {
		buildBasic();
		buildWalls();
		roofed();
	}
}
package com.example.demo.builder;

public class CommonHouse extends AbstractHouse{

	@Override
	public void buildBasic() {
		// TODO Auto-generated method stub
		System.out.println(" 普通房子打地基 ");
	}

	@Override
	public void buildWalls() {
		// TODO Auto-generated method stub
		System.out.println(" 普通房子砌牆 ");
	}

	@Override
	public void roofed() {
		// TODO Auto-generated method stub
		System.out.println(" 普通房子封頂 ");
	}

}
package com.example.demo.builder;

public class Client {
	public static void main(String[] args) {
		AbstractHouse abstractHouse = new CommonHouse();
		abstractHouse.build();
	}
}

傳統方式的問題分析

1)優點是比較好理解,簡單易操作。
2)設計的程式結構,過於簡單, 沒有設計緩存層對象,程式的擴展和維護不好,也就是說,這種設計方案,把產品(即 :房子)和創建產品的過程(即 :建房子流程)封裝在一起,耦合性增強了。
3)解決方案 :將產品和產品建造過程解耦 =》建造者模式。

建造者模式基本介紹

基本介紹
1)建造者模式(Builder Pattern)又叫生成器模式,是一種對象構建模式。它可以將複雜對象的建造過程抽象出來(抽象類別),使這個抽象過程的不同實現方法可以構造出不同表現(屬性)的對象。
2)建造者模式是一步一步創建一個複雜的對象,它允許用戶只通過指定複雜對象的類型和內容就可以構建它們,用戶不需要知道內部的具體構建細節。

建造者模式的四個角色

1)Product(產品角色):一個具體的產品對象。
2)Builder(抽象建造者):創建一個Product對象的各個部件指定的介面/抽象類。
3)ConcreteBuilder(具體建造者):實現介面,構建和裝配各個部件。
4)Director(指揮者):構建一個使用Builder介面的對象。它主要是用於創建一個複雜的對象。它主要有兩個作用,一是:隔離了客戶與對象的生產過程;二是:負責控制產品對象的生產過程。

建造者模式原理類圖

在這裡插入圖片描述

package com.example.demo.builder.improve;

/**
 * 產品 -》Product
 * @author zhaozhaohai
 *
 */
public class House {
	private String baise;
	private String wall;
	private String roofed;
	public String getBaise() {
		return baise;
	}
	public void setBaise(String baise) {
		this.baise = baise;
	}
	public String getWall() {
		return wall;
	}
	public void setWall(String wall) {
		this.wall = wall;
	}
	public String getRoofed() {
		return roofed;
	}
	public void setRoofed(String roofed) {
		this.roofed = roofed;
	}
	
}
package com.example.demo.builder.improve;

/**
 * 抽象的建造者
 * @author zhaozhaohai
 *
 */
public abstract class HouseBuilder {
	protected House house = new House();
	
	/**
	 * 將建造的流程寫好,抽象的方法
	 */
	public abstract void buildBasic();
	public abstract void buildWalls();
	public abstract void roofed();
	
	/**
	 * 建造房子好後,將房子(產品)返回,
	 */
	public House buildHouse() {
		return house;
	}
}
package com.example.demo.builder.improve;

public class CommonHouse extends HouseBuilder{

	@Override
	public void buildBasic() {
		// TODO Auto-generated method stub
		System.out.println(" 普通房子打地基5米 ");
	}

	@Override
	public void buildWalls() {
		// TODO Auto-generated method stub
		System.out.println(" 普通房子砌牆10cm ");
	}

	@Override
	public void roofed() {
		// TODO Auto-generated method stub
		System.out.println(" 普通房子蓋屋頂 ");
	}

}
package com.example.demo.builder.improve;

public class HighHouse extends HouseBuilder{

	@Override
	public void buildBasic() {
		// TODO Auto-generated method stub
		System.out.println(" 高樓的打地基100米 ");
	}

	@Override
	public void buildWalls() {
		// TODO Auto-generated method stub
		System.out.println(" 高樓的砌牆50米 ");
	}

	@Override
	public void roofed() {
		// TODO Auto-generated method stub
		System.out.println(" 高樓的透明的屋頂 ");
	}

}
package com.example.demo.builder.improve;

/**
 * 指揮者,這裡去指定流程,返回產品
 * @author zhaozhaohai
 *
 */
public class HouseDirector {
	private HouseBuilder houseBuilder = null;
	
	/**
	 * 構造器傳入 houseBuilder
	 * @param houseDirector
	 */
	public HouseDirector(HouseBuilder houseBuilder) {
		this.houseBuilder = houseBuilder;
	}

	/**
	 * 通過setter 傳入 houseBuilder
	 * @param houseDirector
	 */
	public void setHouseDirector(HouseBuilder houseBuilder) {
		this.houseBuilder = houseBuilder;
	}
	
	/**
	 * 如何處理建造房子的流程,交給指揮者
	 * @return
	 */
	public House construHouse() {
		houseBuilder.buildBasic();
		houseBuilder.buildWalls();
		houseBuilder.roofed();
		return houseBuilder.buildHouse();
	}
	
}
package com.example.demo.builder.improve;

public class Client {
	public static void main(String[] args) {
		// 蓋普通房子
		CommonHouse commonHouse = new CommonHouse();
		// 準備創建房子的指揮者
		HouseDirector houseDirector = new HouseDirector(commonHouse);
		
		// 完成蓋房子,返回產品(房子)
		House house = houseDirector.construHouse();
	}
}

建造者模式在JDK的應用和源碼分析

1)java.lang.StringBuilder中的建造者模式
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
在這裡插入圖片描述
2)源碼中建造者模式角色分析
(1)Appendable介面定義了多個append方法(抽象方法),即Appendable為抽象建造者,定義了抽象方法
(2)AbstractStringBuilder 實現了Appendable介面方法,這裡的AbstractStringBuilder已經是建造者,只是不能實例化
(3)StringBuilder 即是指揮者角色,同時充當了具體的建造者,建造方法的實現是由AbstractStringBuilder完成,而StringBuilder 繼承了AbstractStringBuilder

建造者模式的註意事項和細節

1)客戶端(使用程式)不必知道產品內部組成的細節,將產品本身與產品的創建過程解耦,使得相同的創建過程可以創建不同的產品對象
2)每一個具體建造者都相對獨立,而與其他的具體建造者無關,因此可以很方便地替換具體建造者或增加新的具體建造者,用戶使用不同的具體建造者即可得到不同的產品對象
3)可以更加精細地控制產品的創建過程。將複雜產品的創建步驟分解在不同的方法中,使得創建過程更加清晰,也更方便使用程式來控制創建過程
4)增加新的具體建造者無須修改原有類庫的代碼,指揮者類針對抽象建造者類編程,系統擴展方便,符合“開閉原則”
5)建造者模式所創建的產品一般具有較多的共同點,其組成部分相似,如果產品之間的差異性很大,則不符合使用建造者模式,因此其使用範圍受到一定的限制。
6)如果產品的內部變化複雜,可能會導致需要定義很多具體建造者類來實現這種變化,導致系統變得很龐大,因此在這種情況下,要考慮是否選擇建造者模式。
7)抽象工廠模式 VS 建造者模式
抽象工廠模式實現對產品家族的創建,一個產品的家族是這樣的一系列產品;具有不同分類維度的產品組合,採用抽象工廠模式不需要關心構建過程,只關心什麼產品由什麼工廠生產即可。而建造者模式則是要求按照指定的藍圖建造產品,它的主要目的是通過組裝零配件而產生一個新產品。


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

-Advertisement-
Play Games
更多相關文章
  • Node.js 非同步編程的直接體現就是回調。 回調函數在完成任務後就會被調用,Node 使用了大量的回調函數,Node 所有 API 都支持回調函數。 例如,我們可以一邊讀取文件,一邊執行其他命令,在文件讀取完成後,我們將文件內容作為回調函數的參數返回。 這樣在執行代碼時就沒有阻塞或等待文件 I/O ...
  • Node.js REPL(Read Eval Print Loop:互動式解釋器) 表示一個電腦的環境,類似 Window 系統的終端或 Unix/Linux shell,我們可以在終端中輸入命令,並接收系統的響應。 Node 自帶了互動式解釋器,可以執行以下任務: 讀取 - 讀取用戶輸入,解析輸入 ...
  • NPM是隨同NodeJS一起安裝的包管理工具 允許用戶從NPM伺服器下載別人編寫的第三方包到本地使用 允許用戶從NPM伺服器下載並安裝別人編寫的命令行程式到本地使用 允許用戶將自己編寫的包或命令行程式上傳到NPM伺服器供別人使用 由於新版的nodejs已經集成了npm,所以npm也一併安裝好了。同樣 ...
  • 1.stop 阻止事件冒泡 2.prevent 阻止預設事件發生 3.capture 當元素髮生冒泡時,先觸髮帶有該修飾符的元素。若有多個該修飾符,則由外而內觸發。 4.passive 不攔截預設事件,每次事件產生,瀏覽器都會去查詢一下是否有preventDefault阻止該次事件的預設動作。我們加 ...
  • 1 "use strict" 2 3 //載入js文件 4 loadFile([ 5 "./js/lib/WebGL.js",//檢查 是否支持webGL 插件 6 "./js/lib/three_114.min.js",//3d庫 7 "js/func.js" 8 ], main); 9 10 / ...
  • 按鈕點選輸入,是一個非常簡單的控制項,20分鐘就能完成的一個控制項。先看效果: 根據以前的設定,通過json數據動態生成這兩個按鈕,示例中這兩個按鈕對應的json代碼: { label:'標題', value:'h2', defaultValue:'h2', inputName:'RxButtonSel ...
  • 記錄大話設計學習過程。 鏈接:https://pan.baidu.com/s/1JNaagbvOkwAHMBe6vdH8lg 提取碼:ko5t 如果能想到多一個動機去改變一個類,那麼這個類負責的職責就多於一個。 單一職責在企業里就能明顯的體現出來,HR一個類、開發人員一個類、項目經理一個類、測試人員 ...
  • 本人免費整理了Java高級資料,涵蓋了Java、Redis、MongoDB、MySQL、Zookeeper、Spring Cloud、Dubbo高併發分散式等教程,一共30G,需要自己領取。傳送門:https://mp.weixin.qq.com/s/osB-BOl6W-ZLTSttTkqMPQ 前 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...