Java設計模式之<建造者模式>

目錄

1、建造者模式

2、建造者模式結構

3、實現

4、工廠模式對比

5、適用場景差異


前言

????????建造者模式是一種創建型設計模式。用于封裝復雜對象的構建過程,通過步驟構建產品類。它包括產品類、抽象建造者具體建造者指揮者角色

????????優點在于靈活性、解耦和易擴展,缺點是增加工作量和效率較低。適用場景如構建套餐、字符串動態構建、StreamAPI操作等。


1、建造者模式

(Builder Pattern)建造者模式定義:封裝一個復雜對象構造過程,并允許按步驟構造。

? ? ? ? 將一個復雜對象的構建(如何分步組裝)和其表示(最后生成的產品)分離。使同樣的構建過程可以創建不同表現(參數組合)的對象。

  • 針對復雜對象,構建流程有“步驟”,可以按需改變每一步內容或順序
  • 最終可以生成不同個性化的產物(同樣流程,不同參數或細節)


2、建造者模式結構

如下所示:

  1. Product(產品類):最終要建造的復雜對象。
  2. Builder(抽象建造者):定義構建產品各部分的接口。
  3. ConcreteBuilder(具體建造者):實現 Builder 接口,每步怎么造。
  4. Director(指揮者):決定調用哪些步驟,以及什么順序,控制“組裝流程”。

3、實現

假設建造一個定制漢堡(面包、肉、蔬菜、醬料等均可變),可以有不同套餐。

1. 產品類

class Burger {private String bread;private String meat;private String vegetable;private String sauce;// setter/getter略@Overridepublic String toString() {return "Burger{" +"bread='" + bread + '\'' +", meat='" + meat + '\'' +", vegetable='" + vegetable + '\'' +", sauce='" + sauce + '\'' +'}';}
}

2. 抽象建造者

interface BurgerBuilder {BurgerBuilder chooseBread(String bread);BurgerBuilder chooseMeat(String meat);BurgerBuilder chooseVegetable(String vegetable);BurgerBuilder chooseSauce(String sauce);Burger build();
}

3. 具體建造者

class DefaultBurgerBuilder implements BurgerBuilder {private Burger burger = new Burger();@Overridepublic BurgerBuilder chooseBread(String bread) {burger.setBread(bread);return this;}@Overridepublic BurgerBuilder chooseMeat(String meat) {burger.setMeat(meat);return this;}@Overridepublic BurgerBuilder chooseVegetable(String vegetable) {burger.setVegetable(vegetable);return this;}@Overridepublic BurgerBuilder chooseSauce(String sauce) {burger.setSauce(sauce);return this;}@Overridepublic Burger build() {return burger;}
}

4. 指揮者 Director(可選)

如果產品組合很復雜,可以有個指揮者預設“套餐”:

class BurgerDirector {public Burger createCheeseBeefBurger(BurgerBuilder builder) {return builder.chooseBread("芝麻面包").chooseMeat("牛肉").chooseVegetable("生菜").chooseSauce("芝士醬").build();}// 也可有 createSpicyChickenBurger() ...
}

5. 客戶端使用

public class TestBuilder {public static void main(String[] args) {BurgerBuilder builder = new DefaultBurgerBuilder();// 自定義裝配Burger burger = builder.chooseBread("全麥").chooseMeat("雞肉").chooseVegetable("番茄").chooseSauce("千島醬").build();System.out.println(burger);// 使用預定義指揮者裝配套餐BurgerDirector director = new BurgerDirector();Burger cheeseBurger = director.createCheeseBeefBurger(new DefaultBurgerBuilder());System.out.println(cheeseBurger);}
}

結果輸出:

Burger{bread='全麥', meat='雞肉', vegetable='番茄', sauce='千島醬'}
Burger{bread='芝麻面包', meat='牛肉', vegetable='生菜', sauce='芝士醬'}

4、工廠模式對比

特點:

  • 創建對象時,一次性指定參數,直接new或工廠create返回對象
  • 不能靈活分步驟定制產物,組合變化很局限
  • 適合產品結構簡單、參數少、變化小的“快速生產”

簡單工廠/工廠方法代碼:

// 簡單工廠
class BurgerFactory {public static Burger createCheeseBurger() {Burger b = new Burger();b.setBread("芝麻面包");b.setMeat("牛肉");b.setVegetable("生菜");b.setSauce("芝士醬");return b;}public static Burger createChickenBurger() { ... }
}// 使用
Burger burger = BurgerFactory.createCheeseBurger();

對比:

  • 工廠模式:側重產物種類,比如“要A還是B”,流程和細節廠內規定死了,客戶端改不了。
  • 建造者模式:側重“每一步都能自由定制和變化”,組裝細節自己掌握,可以一個build流程裝不同產品,還能鏈式調用、流式風格。

5、適用場景差異

如下所示:

?

1、Lombok的@Builder注解

支持鏈式建造大對象。

2、StringBuilder/StringBuffer

3、MyBatis的SqlSessionFactoryBuilder

4、復雜業務DTO裝配,配置文件裝配器

5、Stream API:

將集合類轉為stream流,通過一系列的中間操作和終止操作來生成最終結果。


總結

1、建造者模式適用于:

復雜對象的*組裝、參數變化多、“按步構建”*的場景,強調流程可擴展、定制化強

2、工廠模式適用于:

產品類目變化,強調“要什么生產什么”,但組裝流程是固定的、透明的


參考文章:

1、設計模式第10講——建造者模式(Builder)-CSDN博客文章瀏覽閱讀1.9w次,點贊68次,收藏204次。建造者模式是一種創建型設計模式,用于封裝復雜對象的構建過程,通過步驟構建產品類。它包括產品類、抽象建造者、具體建造者和指揮者角色。優點在于靈活性、解耦和易擴展,缺點是增加工作量和效率較低。適用場景如構建套餐、字符串動態構建、StreamAPI操作等。代碼示例展示了如何用建造者模式構建肯德基套餐。 https://blog.csdn.net/weixin_45433817/article/details/131175862?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522a704756060a8db0d2183b3418eedf674%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=a704756060a8db0d2183b3418eedf674&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-131175862-null-null.142^v102^control&utm_term=%E5%BB%BA%E9%80%A0%E8%80%85%E6%A8%A1%E5%BC%8F&spm=1018.2226.3001.4187

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/93258.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/93258.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/93258.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

fchown/fchownat系統調用及示例

55. fchmod - 通過文件描述符改變文件權限 函數介紹 fchmod是一個Linux系統調用&#xff0c;用于通過文件描述符來改變文件的訪問權限。它是chmod函數的文件描述符版本&#xff0c;避免了路徑名解析。 函數原型 #include <sys/stat.h> #include <unistd.h>int fchm…

20250726-5-Kubernetes 網絡-Service 代理模式詳解(iptables與ipvs)_筆記

一、服務三種常用類型 ?? 1. LoadBalancer類型 工作原理:與NodePort類似,在每個節點上啟用端口暴露服務,同時Kubernetes會請求底層云平臺(如阿里云、騰訊云、AWS等)的負載均衡器,將每個Node([NodeIP]:[NodePort])作為后端添加。 自動化實現:云廠商通過官方實現的控制…

horizon置備出錯

報錯內容如下&#xff1a; [2025/7/28 19:15] 置備 Customization failure: Customization of the guest operating system is not supported due to the given reason: 期間出錯 解決方法&#xff1a;將模板轉換為虛擬機&#xff0c;安裝vmtools&#xff1b;再安裝vmtools之后…

【unitrix】 6.19 Ord特質(ord.rs)

一、源碼 這段代碼定義了一個標記特征&#xff08;marker trait&#xff09;Ord 和三個實現&#xff0c;用于將類型標記與 Rust 標準庫中的 Ordering 枚舉關聯起來。 use crate::sealed::Sealed; use core::cmp::Ordering; use crate::number::{Greater, Equal, Less}; /// 用于…

數據結構之順序表鏈表棧

順序表 什么是 list list 的使用 線性表是什么 順序表是什么 順序表和線性表的關系 順序表和數組的區別 List 和 ArrayList 的關系 如何自己模擬實現 myArrayList ArrayList 的構造 ArrayList 的常見方法 以下兩種寫法有什么區別 ArrayList<Integer> arrayLis…

day062-監控告警方式與Grafana優雅展示

文章目錄0. 老男孩思想-馬太效應1. API監控2. zabbix的API接口2.1 生成zabbix的api token2.2 訪問格式2.3 前端添加web監測3. 監控告警方式3.1 云監控-郵件告警3.1.1 郵箱開啟授權碼3.1.2 zabbix前端配置3.1.3 消息模板3.1.4 配置郵箱收件人信息3.1.5 配置觸發器3.2 企業微信告…

Ettus USRP X410/X440 運行 ADC 自校準

Ettus USRP X410/X440 運行 ADC 自校準 打開一個接收&#xff08;Rx&#xff09;會話到您在設備名稱輸入中指定的設備并返回會話句柄 out&#xff0c;您可以使用該句柄在所有后續 NI-USRP VI 中識別此儀器會話。 支持設備&#xff1a;Ettus USRP X410/X440輸入/輸出 文明.png 會…

Qt元類型系統(QMetaType)詳解

Qt元類型系統詳解一、Qt元類型系統(QMetaType)詳解1. 核心功能2. 注冊機制3. 關鍵技術點4. 信號槽支持5. 流式傳輸支持6. 使用場景7. 注意事項二、完整示例1、基本實例2、基本實例3、元類型在信號槽中的應用4、高級用法三、元對象編譯器moc元對象編譯器&#xff08;Moc&#xf…

《C++繼承詳解:從入門到理解公有、私有與保護繼承》

《C繼承詳解&#xff1a;從入門到理解公有、私有與保護繼承》 文章目錄《C繼承詳解&#xff1a;從入門到理解公有、私有與保護繼承》一、繼承的概念及定義1.1 繼承的概念1.2 繼承定義1.2.1 定義格式1.2.2 繼承基類成員訪問方式的變化1.3 繼承類模版二、基類和派生類間的轉換三、…

佳能iR-ADV C5560復印機如何掃描文件到電腦

打印機與電腦連接首先&#xff0c;確保佳能iR-ADV C5560復印機通過USB或Wi-Fi等網絡連接的方式成功連接到電腦。這可以通過USB線纜或Wi-Fi等網絡來實現。連接完成后&#xff0c;便可利用打印機內置的掃描功能&#xff0c;輕松將文件掃描并傳輸至電腦中。【掃描操作步驟】接下來…

騰訊AI IDE

1.官網說明&#xff1a;打開騰訊AI IDE官網。2.安裝說明&#xff1a;安裝成功后的界面。3.登錄 說明&#xff1a;通過郵箱和密碼登錄。4.成功說明&#xff1a;成功登錄如下界面。5.簡單一問說明&#xff1a;理解能力感覺不錯。擁有Claude-3.7-Sonnet??&#xff0c;??Claude…

【LeetCode 熱題 100】(一)哈希

1. 兩數之和 class Solution {public int[] twoSum(int[] nums, int target) {int length nums.length;// 1.聲明一個hashmap {nums[i], i}HashMap<Integer, Integer> map new HashMap<>();for (int i 0; i < length; i) {int second target - nums[i];if(m…

PMOS快速關斷電路、PMOS加速關斷電路

[電源系列]二、低成本MOS快速關斷電路原理分析 MOS的減速加速電路設計 分享一個微碧在網上看到的電路情況 加速電路1 PMOS關斷時間較長。 當用100kHz的頻率驅動PMOS時&#xff0c;PMOS G極的電壓信號并不是一個脈沖波&#xff0c;PMOS一直處于線性放大的狀態&#xff0c;并且…

Docker筆記(基本命令、掛載本地gpu、Dockerfile文件配置、數據掛載、docker換源)

Docker 主要用于環境搭建以及服務部署 基本命令 1.查看鏡像 docker images 2.查看容器 docker ps # 查看容器僅僅為查看運行狀態的容器 docker ps -a # 查看所有狀態的容器3.退出容器 exit4.刪除鏡像、容器 docker rm 鏡像ID docker rm 容器ID docker rm -f 容器ID # 強制刪除…

算法競賽階段二-數據結構(37)數據結構循環鏈表模擬實現

之前單鏈表中&#xff0c;數組全初始化為0&#xff0c;末尾最后一個next 存的就是0&#xff0c;指向的就是頭節點循環鏈表的基本概念循環鏈表是一種特殊的鏈表&#xff0c;其尾節點的指針域指向頭節點&#xff0c;形成一個閉環。與普通單鏈表相比&#xff0c;循環鏈表的遍歷需要…

20250727讓飛凌OK3576-C開發板在Rockchip的原廠Android14下通過耳機播音

20250727讓飛凌OK3576-C開發板在Rockchip的原廠Android14下通過耳機播音 2025/7/27 23:28緣起&#xff1a;很容易知道 飛凌OK3576-C開發板 使用的聲卡芯片是 NAU88C22YG 新唐科技(NUVOTON) NAU8822LYG NAU88C22YG 新唐立體聲音頻編解碼芯片原理圖&#xff1a;OK3576-C V1.2_202…

正向代理和反向代理的理解

**正向代理&#xff08;Forward Proxy&#xff09;和反向代理&#xff08;Reverse Proxy&#xff09;**是兩種不同類型的代理服務器&#xff0c;它們在數據傳輸過程中扮演的角色、使用場景以及工作方式都有所不同。 正向代理&#xff08;Forward Proxy&#xff09; 定義與作用&…

Java 后端 Cookie Session Token會話跟蹤技術

概述 會話從字面理解就是"兩方交流"&#xff0c;那問題就來了&#xff0c;HTTP&#xff08;超文本傳輸協議&#xff09;里面的"傳輸"不就包含了"兩方交流"的意思嗎&#xff1f;為什么要多此一舉提出會話技術呢&#xff1f; 談到這個&#xff0c;…

智譜AI GLM大模型 GLM-4-Plus的快速使用 ChatOpenAI類來調用GLM-4模型

智譜AIGLM-4&#xff0c;2024年1月16日發布的第四代基座大模型&#xff0c;其整體性能相較前代提升近60%&#xff0c;多維度指標逼近OpenAI的GPT-4水平。該模型支持128K上下文窗口&#xff08;約300頁文本處理能力&#xff09;&#xff0c;在長文本信息處理中實現100%精度召回。…

AsyncLocal淺復制的問題解決方案

針對C#中AsyncLocal<T>淺復制問題&#xff0c;以下是幾種主要的解決方案&#xff1a; 1. 使用不可變對象&#xff08;推薦&#xff09; 將存儲在AsyncLocal<T>中的對象設計為不可變的&#xff0c;避免修改共享狀態&#xff1a; public class ImmutableUserContext …