23種設計模式——抽象工廠模式(Abstract Factory Pattern)詳解

?作者簡介:大家好,我是 Meteors., 向往著更加簡潔高效的代碼寫法與編程方式,持續分享Java技術內容。
🍎個人主頁:Meteors.的博客
💞當前專欄:設計模式
?特色專欄:知識分享
🥭本文內容:23種設計模式——抽象工廠模式(Abstract Factory Pattern)
📚 ** ps **? :閱讀文章如果有問題或者疑惑,歡迎在評論區提問或指出。


目錄

一. 背景

二. 介紹

三.?核心角色

四. 代碼示例

1.??抽象產品 & 具體產品?

2.?抽象工廠 & 具體工廠?

3.?客戶端代碼?

五.??與簡單工廠、工廠方法的區別

六. 抽象工廠模式的優缺點

七. 總結與應用場景


一. 背景

對于工廠方法模式,會有一個工廠類里面有一個抽象工廠方法并且返回類型是一個接口基類(大白話講就是這個方法創建了一個基類的不同實現類,如基類為按鈕,我們就可以通過這個方法創建圓形按鈕或者方形按鈕);

但如果現在有個界面,不僅僅要創建不同類型的按鈕,還要創建不同類型的文本框、字體......這種情況怎么辦?其實這個時候我們就可以創建一個抽象工廠模式(就是這個界面),里面有多個抽象工廠方法(創建按鈕的、創建文本框的、創建字體的......)。抽象工廠。它本質上是??多個工廠方法的組合,這些方法共同生產一個產品族。


二. 介紹

抽象工廠模式??是一種創建型設計模式,它提供一個接口,用于創建??相關或依賴對象??的??家族??,而不需要明確指定具體類。

你可以將其理解為“工廠的工廠”。客戶端代碼不直接通過new來實例化具體的產品,而是通過一個抽象的接口來創建一整組相關的產品。這使得客戶端代碼與具體的產品類解耦,并且能確保所創建的產品是相互兼容的。


三.?核心角色

  1. ??抽象工廠??:聲明一個創建??一族產品??(多個不同產品等級)的接口,包含多個創建產品的方法,如?createButton(),?createTextBox()
  2. ??具體工廠??:實現抽象工廠的接口,負責創建某一族具體的產品。例如,WindowsFactory?創建 Windows 風格的按鈕和文本框,MacFactory?創建 Mac 風格的按鈕和文本框。
  3. ??抽象產品??:聲明每種產品類型的接口。例如,Button?和?TextBox
  4. ??具體產品??:實現抽象產品接口,由具體工廠創建。例如,WindowsButton,?MacButton,?WindowsTextBox,?MacTextBox

四. 代碼示例

用一個界面為例:

1.??抽象產品 & 具體產品?

// 抽象產品:按鈕
public interface Button {void render();void onClick();
}// 具體產品:Windows按鈕
public class WindowsButton implements Button {@Overridepublic void render() {System.out.println("渲染一個Windows風格的按鈕");}@Overridepublic void onClick() {System.out.println("Windows按鈕被點擊!");}
}// 具體產品:Mac按鈕
public class MacButton implements Button {@Overridepublic void render() {System.out.println("渲染一個Mac風格的按鈕");}@Overridepublic void onClick() {System.out.println("Mac按鈕被點擊!");}
}// 抽象產品:文本框
public interface TextBox {void render();
}// 具體產品:Windows文本框
public class WindowsTextBox implements TextBox {@Overridepublic void render() {System.out.println("渲染一個Windows風格的文本框");}
}// 具體產品:Mac文本框
public class MacTextBox implements TextBox {@Overridepublic void render() {System.out.println("渲染一個Mac風格的文本框");}
}

2.?抽象工廠 & 具體工廠?

// 抽象工廠
public interface GUIFactory {Button createButton();TextBox createTextBox();
}// 具體工廠:Windows工廠
public class WindowsFactory implements GUIFactory {@Overridepublic Button createButton() {return new WindowsButton();}@Overridepublic TextBox createTextBox() {return new WindowsTextBox();}
}// 具體工廠:Mac工廠
public class MacFactory implements GUIFactory {@Overridepublic Button createButton() {return new MacButton();}@Overridepublic TextBox createTextBox() {return new MacTextBox();}
}

3.?客戶端代碼?

客戶端代碼只依賴抽象工廠和抽象產品,從而與具體平臺解耦。

public class Application {private Button button;private TextBox textBox;// 通過構造器注入一個具體的工廠public Application(GUIFactory factory) {button = factory.createButton();textBox = factory.createTextBox();}public void renderUI() {button.render();textBox.render();}public static void main(String[] args) {// 根據配置或環境決定使用哪種工廠GUIFactory factory;String osName = System.getProperty("os.name").toLowerCase();if (osName.contains("win")) {factory = new WindowsFactory();} else {factory = new MacFactory();}Application app = new Application(factory);app.renderUI();// 輸出:// 如果是Windows: //   渲染一個Windows風格的按鈕//   渲染一個Windows風格的文本框// 如果是Mac://   渲染一個Mac風格的按鈕//   渲染一個Mac風格的文本框}
}

五.??與簡單工廠、工廠方法的區別

特征簡單工廠工廠方法抽象工廠
??核心思想??由一個工廠類根據傳入的參數,??靜態??地決定創建哪一種產品。定義一個創建對象的接口,但讓??子類??決定實例化哪一個類。提供一個接口,用于創建??相關或依賴對象??的??家族??,而不指定具體類。
??工廠角色??一個??具體工廠??類,包含創建所有產品的邏輯。一個??抽象工廠??接口和多個??具體工廠??實現(每個對應一個產品)。一個??抽象工廠??接口和多個??具體工廠??實現(每個對應一族產品)。
??產品維度????一個產品等級??(例如:只有按鈕)。??一個產品等級??(例如:只有按鈕)。??多個產品等級??(例如:按鈕、文本框、復選框等??一套產品??)。
??擴展性????違反開閉原則??。要新增產品,必須修改工廠類的邏輯。??符合開閉原則??。要新增產品,只需新增一個具體工廠即可。??符合開閉原則??。但要新增一個產品族(如Linux主題)很容易,??新增一個產品等級??(如新增Slider滑塊)很困難,需要修改所有工廠接口和類。
??復雜度/適用場景??簡單,適用于產品類型較少且幾乎不會變化的場景。適中,適用于產品結構單一但需要靈活擴展的場景。復雜,適用于需要創建一整系列相互關聯、相互依賴的產品,并保證它們兼容的場景。

演進關系(從簡單到復雜):

  1. .簡單工廠??:如果你只有一個產品(比如只有Button),用簡單工廠就夠了。
  2. 工廠方法??:當你的產品變得復雜,或者你希望擴展時不修改原有代碼(比如未來要加LinuxButton),你就為每種按鈕建立一個專門的工廠。
  3. 抽象工廠??:當你不止有按鈕,還有文本框、復選框等??一整套需要搭配使用??的產品時,工廠方法就不夠了。你需要一個能創建??整套產品??的工廠,這就是抽象工廠。它本質上是??多個工廠方法的組合??,這些方法共同生產一個產品族。

六. 抽象工廠模式的優缺點

??優點:??

  • 保證了產品的兼容性??:確保客戶端始終只使用同一產品族中的對象。你不會把一個Windows按鈕和一個Mac文本框混在一起用。
  • 解耦客戶端與具體產品??:客戶端代碼只面向抽象接口編程,使得切換整個產品族變得非常容易(只需換一個具體工廠)。
  • 符合開閉原則??:易于擴展新的產品族(如新增一個LinuxFactory)。

??缺點:??

  • 難以支持新的產品種類??:這是最大的缺點。如果要為所有工廠增加一個新的產品(如在產品族中增加Slider滑塊),就需要修改抽象工廠接口GUIFactory,這會導致所有具體工廠類(WindowsFactory,?MacFactory)都需要被修改,違反了開閉原則。
  • 增加了系統的復雜性??:類會變得非常多(n個產品族 * m個產品等級 = n*m個類)。

七. 總結與應用場景

??抽象工廠模式的核心是創建產品族。??

??典型應用場景:??

  • 系統需要獨立于其產品的創建、組合和表示時??。
  • ??系統需要配置多個產品族中的某一個時??。
  • 需要強調一系列相關產品對象的設計以便進行聯合使用時??。
  • 希望提供一個產品類庫,但只想暴露它們的接口而不是實現時??。

??經典例子:??

  • ?跨平臺GUI開發??(如Java AWT/Swing, QT)。
  • 數據庫訪問層??:Connection,?Command,?DataAdapter?構成一個產品族,可以輕松在?SqlServerFactory?和?OracleFactory?之間切換。
  • 游戲開發??:為不同風格(科幻、中世紀)的場景創建一套主題資源(建筑、士兵、植被)。
  • ??日志記錄器??:創建一套相關的日志組件(記錄器、格式化器、附加器)。

最后,

? ? ? ? 其它設計模式會陸續更新,希望文章對你有所幫助!

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

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

相關文章

本地部署開源數據生成器項目實戰指南

本地部署開源數據生成器項目實戰指南 前言 在當今大數據和人工智能時代,高質量數據集對于模型訓練和算法開發至關重要。然而,獲取真實且合規的數據集往往面臨隱私、成本和法律等多重挑戰。合成數據生成技術為此提供了優雅的解決方案,它能夠…

2025React面試題集錦

1. React 是什么?它有哪些主要特點? React 是由Facebook開發的開源JavaScript庫,用于構建用戶界面(UI),尤其適合開發復雜的單頁應用(SPA)。 主要特點: 聲明式編程:只需描述UI應該是什么樣子(如return <div>Hello</div>),React會自動處理DOM更新,無需…

設計模式:迭代器模式(Iterator Pattern)

文章目錄一、概念二、實例分析三、示例代碼一、概念 迭代器模式 是一種 行為型設計模式&#xff0c;用于在不暴露集合對象內部結構的前提下&#xff0c;順序訪問集合中的元素。 換句話說&#xff1a; 集合類只負責數據存儲&#xff1b;迭代器類負責遍歷集合&#xff1b;使用者…

Vue 3 學習路線指南

階段一:基礎入門 (1-2周) 1.1 環境準備 # 安裝 Node.js (推薦 18+ 版本) # 安裝 Vue CLI 或使用 Vite npm create vue@latest my-vue-app cd my-vue-app npm install npm run dev1.2 Vue 3 核心概念 響應式系統:ref(), reactive(), computed() 組合式 API:setup() 函數 模…

使用 `hover:not-[:has(:hover)]` 避免「父元素和子元素同時 hover」時的樣式沖突

:hover:not-(:has(:hover)) has() CSS 4 引入的“父選擇器”&#xff0c;意思是&#xff1a;匹配那些里面包含某個子元素/狀態的元素。 例如&#xff1a;:has(:hover) 表示「自身包含正在被 hover 的子元素」。 :not() 取反偽類&#xff0c;表示不匹配里面的條件。 比如我…

第三十天-DMA串口實驗

一、DMA概述二、DMA通道注意&#xff0c;想要往串口中寫數據&#xff0c;外部請求信號應該是USARTx_TX&#xff0c;當DR寄存器為空時&#xff0c;產生TX信號&#xff0c;請求DMA。反之&#xff0c;從串口中讀數據&#xff0c;外部請求信號應該是USARTx_RX&#xff0c;當DR寄存器…

C/C++ 中的inline(內聯函數關鍵字)詳解

在 C/C 編程中&#xff0c;函數調用雖然帶來了代碼復用和可讀性提升&#xff0c;但頻繁調用小型函數可能會產生額外的調用開銷&#xff08;call overhead&#xff09;&#xff0c;比如棧幀的建立與銷毀、參數傳遞等。 為了減少這種開銷&#xff0c;C 引入了 inline&#xff08;…

2025 年高教社杯全國大學生數學建模競賽A 題 煙幕干擾彈的投放策略完整成品 思路 模型 代碼 結果 全網首發高質量!!!

煙幕干擾彈主要通過化學燃燒或爆炸分散形成煙幕或氣溶膠云團,在目標前方特定空域形成遮蔽&#xff0c;干擾敵方導彈&#xff0c;具有成本低、效費比高等優點。隨著煙幕干擾技術的不斷發展&#xff0c;現已有多種投放方式完成煙幕干擾彈的定點精確拋撒,即在拋撒前能精確控制煙幕…

嵌入式第四十五天(51單片機相關)

一.1.CPU、MPU、MCU、GPU&#xff1a; CPU&#xff08;中央處理器&#xff09;&#xff1a;計算機的核心部件&#xff0c;負責執行指令和處理數據。 MPU&#xff08;微處理器&#xff09;&#xff1a;通常指更通用的處理器&#xff0c;強調計算能力。 MCU&#xff08;微控制器&…

今天面了一個Java后端工程師,真的讓我猛抬頭

今天面了一個Java后端工程師,真的讓我猛抬頭啊. 現在面試不像傳統的八股文面試,我更多問的都是項目場景相關的問題,但是都能回答的不錯.這一點我還是很驚訝的。 不僅如此,她的技術也很扎實,對Java核心機制&#xff08;JVM、并發、集合等&#xff09;理解深入&#xff0c;回答…

攔截器和過濾器(理論+實操)

攔截器和過濾器 本文旨在夯實基礎以及實戰加深理解,目的是更深的理解以便掌握,希望能跟著動手敲一遍,絕對受益匪淺 在本文,我會先給出兩者的區別(理論知識),隨后是兩者各自的實操實現 文章目錄攔截器和過濾器什么是過濾器和攔截器?1.過濾器2.攔截器執行整體流程攔截器和過濾器…

HTB 賽季8靶場 - Guardian

各位好&#xff0c;最近我的kali崩掉了&#xff0c;崩掉了&#xff0c;建議大家避K 番茄C盤瘦身&#xff0c;這家伙修改了我的avrt.dll文件&#xff0c;導致virtualbox不接受我的avrt.dll文件的簽名了&#xff0c;從而導致virtualbox的虛擬機環境全崩無法開機。弄了幾天&#x…

Rust+slint實現一個登錄demo

系列文章目錄 文章目錄系列文章目錄前言一、為什么前端選擇slint而不是Tauri或者其他GUI框架二、開發工具三、代碼編寫項目結構前端代碼編寫后端開發編寫運行效果總結前言 本文章就是一個簡單rust全棧編程的一個小小的示例供rust新手閱讀學習。 一、為什么前端選擇slint而不是…

2025前端面試題及答案(詳細)

HTML5 的新特性有哪些&#xff1f;簡約版本&#xff1a;“HTML5 新特性主要體現在六個方面&#xff1a; 第一&#xff0c;語義化標簽&#xff0c;比如 header、footer、nav 等&#xff0c;讓頁面結構更清晰&#xff1b; 第二&#xff0c;表單增強&#xff0c;新增了 date、emai…

分詞器詳解(二)

&#x1f50d; 第2層&#xff1a;中等深度&#xff08;15分鐘理解&#xff09; 1. 理論基礎 1.1 BPE的數學原理 核心思想&#xff1a;通過迭代合并高頻字符對構建詞匯表 算法形式化&#xff1a; 初始化詞匯表 V0{c1,c2,...,cn}V_0 \{c_1, c_2, ..., c_n\}V0?{c1?,c2?,...,c…

嵌入式學習 51單片機(3)

UART 概述通用異步收發器&#xff08;UART&#xff09;是一種全雙工、串行、異步通信協議&#xff0c;常用于設備間數據傳輸。包含兩根信號線&#xff1a;RXD&#xff08;接收信號線&#xff09;TXD&#xff08;發送信號線&#xff09;通信方式單工通信方向固定&#xff0c;僅支…

Redis AOF 持久化:銀行的 “交易流水單” 管理邏輯

目錄 一、AOF 的核心邏輯&#xff1a;“每筆交易都記流水” 二、AOF 的三個步驟&#xff1a;從 “臨時記錄” 到 “正式歸檔” 1. 命令追加&#xff1a;記到 “臨時小本本” 2. 寫入與同步&#xff1a;抄到 “正式流水冊” 3. AOF 還原&#xff1a;拿 “流水冊” 重放交易…

代碼隨想錄訓練營第三十天|LeetCode452.用最少數量的箭引爆氣球、LeetCode435.無重疊空間、LeetCode763.劃分字母空間

452.用最少數量的箭引爆氣球 貪心算法 重合最多的氣球射一箭&#xff0c;就是局部用箭數量最少的&#xff0c;全局的用箭數量就是最少的。 首先對二維數組進行排序&#xff0c;這樣就可以讓氣球更加緊湊。 思路&#xff1a;當前氣球是否和上一個氣球區間重合&#xff0c;如…

數據庫事務隔離級別與 MVCC 機制詳解

最近在準備面試&#xff0c;正把平時積累的筆記、項目中遇到的問題與解決方案、對核心原理的理解&#xff0c;以及高頻業務場景的應對策略系統梳理一遍&#xff0c;既能加深記憶&#xff0c;也能讓知識體系更扎實&#xff0c;供大家參考&#xff0c;歡迎討論。在數據庫并發操作…

【Cursor-Gpt-5-high】StackCube-v1 任務訓練結果不穩定性的分析

1. Prompt 我是機器人RL方向的博士生正在學習ManiSkill&#xff0c;在學習時我嘗試使用相同命令訓練同一個任務&#xff0c;但是我發現最終的 success_once 指標并不是相同的&#xff0c;我感到十分焦慮&#xff0c; 我使用的命令如下&#xff1a; python sac.py --env_id"…