【設計模式】抽象工廠模式 (工具(Kit)模式)

抽象工廠模式(Abstract Factory Pattern)詳解


一、抽象工廠模式簡介

抽象工廠模式(Abstract Factory Pattern) 是一種 創建型設計模式(對象創建型模式),它提供了一種創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
抽象工廠模式的核心在于“抽象”,通過定義一個創建對象的接口,但由子類決定要實例化的類是哪一個。

你可以這樣理解:

“抽象工廠就像是一個‘品牌制造商’,根據不同的需求生產出不同品牌的同類產品(如手機、電腦),每個品牌的產品都是相關的,但具體實現各有特色。”

工廠方法模式
每個具體工廠只有一個或者一組重載的工廠方法,只能生產一種產品,可能會導致系統中存在大量的工廠類,勢必會增加系統的開銷
抽象工廠模式
一個工廠可以生產一系列產品(一族產品),極大減少了工廠類的數量

產品等級結構:產品等級結構即產品的繼承結構
產品族:產品族是指由同一個工廠生產的,位于不同產品等級結構中的一組產品

在這里插入圖片描述
當系統所提供的工廠生產的具體產品并不是一個簡單的對象,而是多個位于不同產品等級結構、屬于不同類型的具體產品時就可以使用抽象工廠模式。
抽象工廠模式是所有形式的工廠模式中最為抽象和最具一般性的一種形式。

又稱為工具(Kit)模式
抽象工廠模式中的具體工廠不只是創建一種產品,它負責創建一族產品
當一個工廠等級結構可以創建出分屬于不同產品等級結構的一個產品族中的所有對象時,抽象工廠模式比工廠方法模式更為簡單、更有效率。

抽象工廠模式包含以下4個角色
AbstractFactory(抽象工廠)
ConcreteFactory(具體工廠)
AbstractProduct(抽象產品)
ConcreteProduct(具體產品)

在這里插入圖片描述


二、解決的問題類型

抽象工廠模式主要用于解決以下問題:

  • 需要創建一系列相關對象:這些對象通常是一起使用的,例如一套圖形界面組件(按鈕、文本框等)。
  • 希望隱藏具體產品的創建邏輯:避免客戶端直接使用 new 關鍵字來實例化具體類。
  • 支持擴展性:新增產品族時只需添加新的具體工廠和產品實現,無需修改已有代碼。

三、使用場景

場景示例
UI 組件庫如 Windows 和 Mac 系統下的按鈕、窗口等組件
數據庫連接池提供多種數據庫的連接管理(MySQL, PostgreSQL 等)
游戲中的角色裝備系統不同等級的角色擁有不同級別的武器和防具

一個系統不應當依賴于產品類實例如何被創建、組合和表達的細節。
系統中有多于一個的產品族,但每次只使用其中某一產品族。
屬于同一個產品族的產品將在一起使用,這一約束必須在系統的設計中體現出來。
產品等級結構穩定,設計完成之后,不會向系統中增加新的產品等級結構或者刪除已有的產品等級結構。


四、核心概念

  1. AbstractFactory(抽象工廠):聲明一組用于創建抽象產品的方法。
  2. ConcreteFactory(具體工廠):實現抽象工廠中定義的方法,負責創建具體產品對象。
  3. AbstractProduct(抽象產品):為每類產品定義接口或基類。
  4. ConcreteProduct(具體產品):實現抽象產品接口的具體類。

五、實際代碼案例(Java)

我們以“跨平臺UI組件”為例,演示抽象工廠模式的應用。假設我們需要在Windows和MacOS平臺上顯示按鈕和文本框。

1. 定義抽象產品接口

// 按鈕接口
public interface Button {void paint();
}// 文本框接口
public interface TextBox {void displayText(String text);
}

2. 創建具體產品類

// Windows風格按鈕
public class WindowsButton implements Button {@Overridepublic void paint() {System.out.println("繪制 Windows 樣式的按鈕");}
}// MacOS風格按鈕
public class MacOSButton implements Button {@Overridepublic void paint() {System.out.println("繪制 MacOS 樣式的按鈕");}
}// Windows風格文本框
public class WindowsTextBox implements TextBox {@Overridepublic void displayText(String text) {System.out.println("在 Windows 樣式的文本框中顯示: " + text);}
}// MacOS風格文本框
public class MacOSTextBox implements TextBox {@Overridepublic void displayText(String text) {System.out.println("在 MacOS 樣式的文本框中顯示: " + text);}
}

3. 定義抽象工廠接口

// GUI工廠接口
public interface GUIFactory {Button createButton();TextBox createTextBox();
}

4. 創建具體工廠類

// Windows風格GUI工廠
public class WindowsFactory implements GUIFactory {@Overridepublic Button createButton() {return new WindowsButton();}@Overridepublic TextBox createTextBox() {return new WindowsTextBox();}
}// MacOS風格GUI工廠
public class MacOSFactory implements GUIFactory {@Overridepublic Button createButton() {return new MacOSButton();}@Overridepublic TextBox createTextBox() {return new MacOSTextBox();}
}

5. 客戶端測試類

public class Client {private Button button;private TextBox textBox;public Client(GUIFactory factory) {button = factory.createButton();textBox = factory.createTextBox();}public void render() {button.paint();textBox.displayText("Hello World!");}public static void main(String[] args) {String platform = "Windows"; // 假設當前平臺為WindowsGUIFactory factory;if (platform.equals("Windows")) {factory = new WindowsFactory();} else {factory = new MacOSFactory();}Client app = new Client(factory);app.render();}
}

輸出結果(假設平臺為Windows):

繪制 Windows 樣式的按鈕
在 Windows 樣式的文本框中顯示: Hello World!

典型代碼

典型的抽象工廠類代碼:

abstract class AbstractFactory
{
public abstract AbstractProductA CreateProductA(); //工廠方法一
public abstract AbstractProductB CreateProductB(); //工廠方法二
……
}

典型的具體工廠類代碼:

class ConcreteFactory1 : AbstractFactory
{//工廠方法一
public override AbstractProductA CreateProductA() 
{return new ConcreteProductA1();
}
//工廠方法二
public override AbstractProductB CreateProductB() 
{return new ConcreteProductB1();
}
……
}

其他案例

  1. 某軟件公司要開發一套界面皮膚庫,可以對基于.NET平臺的桌面軟件進行界面美化。用戶在使用時可以通過菜單來選擇皮膚,不同的皮膚將提供視覺效果不同的按鈕、文本框、組合框等界面元素,例如春天(Spring)風格的皮膚將提供淺綠色的按鈕、綠色邊框的文本框和綠色邊框的組合框,而夏天(Summer)風格的皮膚則提供淺藍色的按鈕、藍色邊框的文本框和藍色邊框的組合框,其結構示意圖如下圖所示:
    在這里插入圖片描述
    該皮膚庫需要具備良好的靈活性和可擴展性,用戶可以自由選擇不同的皮膚,開發人員可以在不修改既有代碼的基礎上增加新的皮膚。
    現使用抽象工廠模式來設計該界面皮膚庫。

在這里插入圖片描述

  1. 電器工廠
    一個電器工廠可以產生多種類型的電器,如海爾工廠可以生產海爾電視機、海爾空調等,TCL工廠可以生產TCL電視機、TCL空調等,相同品牌的電器構成一個產品族,而相同類型的電器構成了一個產品等級結構,現使用抽象工廠模式模擬該場景

在這里插入圖片描述

  1. 數據庫操作工廠
    某系統為了改進數據庫操作的性能,自定義數據庫連接對象Connection和語句對象Statement,可針對不同類型的數據庫提供不同的連接對象和語句對象,如提供Oracle或SQL Server專用連接類和語句類,而且用戶可以通過配置文件等方式根據實際需要動態更換系統數據庫。使用抽象工廠模式設計該系統。

在這里插入圖片描述


六、優缺點分析

優點描述
? 統一接口通過抽象層隔離了具體產品的創建過程,使得客戶端僅需知道抽象接口即可
? 易于擴展新增產品族時只需添加新的具體工廠和產品實現,不影響現有代碼
? 增強靈活性可以輕松切換到不同的產品族
缺點描述
? 增加復雜度引入了額外的抽象層次,可能使系統更加復雜。增加新的產品等級結構麻煩,需要對原有系統進行較大的修改,甚至需要修改抽象層代碼,這顯然會帶來較大的不便,違背了開閉原則
? 不便于單獨替換產品更換某一具體產品時可能需要修改所有相關工廠類

七、與其他模式對比(補充)

模式名稱目標
簡單工廠模式通過靜態方法集中創建對象,適用于單一產品族的情況
工廠方法模式提供一個創建對象的接口,但由子類決定實例化哪一個類
抽象工廠模式創建一系列相關或相互依賴的對象,適合多個產品族的場景

八、最終小結

抽象工廠模式是一種強大的創建型設計模式,特別適用于那些需要創建一系列相關對象且希望保持高度靈活性和可擴展性的場景。通過將對象的創建邏輯封裝在抽象工廠中,我們可以有效地分離關注點,提高系統的模塊化程度。

在開發跨平臺應用、多數據庫支持系統、游戲引擎等項目中,抽象工廠模式能夠幫助你更好地組織代碼結構,減少重復代碼,并提高系統的可維護性和可擴展性。


📌 一句話總結:

抽象工廠模式就像一個“產品生產線”,可以根據不同的需求生產出一系列配套的產品,確保產品之間的一致性和兼容性。


? 推薦使用場景:

  • 當你需要創建一組相關的對象時;
  • 希望將對象創建的邏輯集中在一處進行管理;
  • 需要在運行時動態選擇產品族。

擴展

開閉原則的傾斜性

增加產品族
對于增加新的產品族,抽象工廠模式很好地支持了開閉原則,只需要增加具體產品并對應增加一個新的具體工廠,對已有代碼無須做任何修改
增加新的產品等級結構
對于增加新的產品等級結構,需要修改所有的工廠角色,包括抽象工廠類,在所有的工廠類中都需要增加生產新產品的方法,違背了開閉原則

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

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

相關文章

Android初學者系統開發學習路線參考

Android初學者系統開發學習路線參考 文章目錄Android初學者系統開發學習路線參考一、前言二、Android初學的學習計劃第一階段(一個月)UI相關學習:開發環境與 UI 基礎,第一周:UI 控件與布局進階,第二周&…

擴散LLM推理新范式:打破生成長度限制,實現動態自適應調節

隨著 Gemini-Diffusion,Seed-Diffusion 等擴散大語言模型(DLLM)的發布,這一領域成為了工業界和學術界的熱門方向。但是,當前 DLLM 存在著在推理時必須采用預設固定長度的限制,對于不同任務都需要專門調整才…

【ee類保研面試】其他類---計算機網絡

25保研er,希望將自己的面試復習分享出來,供大家參考 part0—英語類 part1—通信類 part2—信號類 part3—高數類 part100—self項目準備 文章目錄計算機網絡知識點大全**計算機網絡知識點總結**一、五層協議模型二、OSI七層模型補充三、TCP 與 UDP 及區別…

Python-機器學習(一)——特征工程

目錄 特征工程 一、特征提取 1、字典特征提取 2、文本特征提取 2.1 英文文本提取 2.2 中文文本提取 3、TF-IDF文本特征詞的重要程度特征提取 二、無量綱化-預處理 1 MinMaxScaler 歸一化 2 normalize歸一化 3 StandardScaler 標準化 三、特征降維 1、特征選擇 1.…

談談SQL計算存儲引擎中的索引和計算

背景 最近在這家公司做了一些事情,做的事情和以往的工作不太一樣,不一樣的點呢就是 之前我主要的工作是關注計算這方面,因為數據量大,研究的是怎么加速查詢,怎么研究規則去優化,怎么去解規則的bug等等。因為…

vscode.window.activeTextEditor 獲取不到 png 圖片路徑問題

vscode 的 extensions 插件開發時用 vscode.window.activeTextEditor?.document.uri 獲取不到編輯器打開的圖片路徑,文檔路徑可以獲取到。個人猜測因為圖片不能編輯,所以沒有 activeTextEditor 屬性吧。解決辦法:巧用右鍵獲取路徑和相對的路…

Java 大視界 -- Java 大數據在智能醫療手術機器人操作數據記錄與性能評估中的應用(390)

Java 大視界 -- Java 大數據在智能醫療手術機器人操作數據記錄與性能評估中的應用(390)引言:正文:一、傳統手術機器人的 “黑箱困境”:記不全、算不清、追不到1.1 設備與臨床的 “斷層”1.1.1 數據記錄 “太粗放”1.1.…

C++的結構體指針

結構體變量和結構體指針的區別特性結構體變量結構體指針存儲內容結構體的實際數據內存地址內存開銷結構體總大小固定4/8字節(指針大小)成員訪問運算符.->函數傳參時的行為值拷貝(新副本)地址傳遞(操作原數據&#x…

pdf文件轉word免費使用幾個工具

在線工具(無需安裝) Smallpdf ? 核心功能: 網頁端直接操作,支持 PDF 與 Word 格式互轉 免費用戶每日限 2 次轉換(免注冊) 自動清除服務器文件,確保隱私安全 🔗 訪問鏈接&#xff1a…

Vue3 組件化開發

文章目錄前言組件化開發底部菜單 TabMenu父子組件相互傳數據父傳子:自定義屬性子傳父:自定義事件父子組件互傳案例插槽 slot多個插槽總結組件化開發總結Vue組件的基本組成子組件使用的三個步驟父子組件相互傳遞數據前言 提示:這里可以添加本…

服務器硬件電路設計之I2C問答(二):I2C總線的傳輸速率與上拉電阻有什么關系?

I2C 總線傳輸速率與上拉電阻關系密切。上拉電阻阻值決定總線電平切換速度:電阻越小,充放電電流越大,信號邊沿更陡,支持更高速率(如 400kHz 快速模式);電阻過大則切換慢,限制速率&…

大語言模型提示工程與應用:LLMs文本生成與數據標注實踐

提示詞應用實踐 學習目標 本課程通過LLMs生成情感分析樣本和標注葡萄9品鑒數據,展示了其文本生成和數據標注能力。同時,利用PAL模型解決日期計算問題,學習了LLMs與編程運行時結合實現復雜推理的方法,為自然語言處理應用提供了實…

node.js 零基礎入門

Node.js 零 基礎入門與核心語法 適用對象:完全沒接觸過 Node.js 的同學 目標:從 0 到能寫 CLI、小型 HTTP 服務、文件腳本、調用系統/網絡資源 目錄 什么是 Node.js安裝與運行運行腳本與 REPL模塊體系:CommonJS 與 ES Modules基礎語法在 Node…

《Day3-PyTorch 自動微分入門:從計算圖到梯度下降的實踐指南》

八、自動微分自動微分模塊torch.autograd負責自動計算張量操作的梯度,具有自動求導功能。自動微分模塊是構成神經網絡訓練的必要模塊,可以實現網絡權重參數的更新,使得反向傳播算法的實現變得簡單而高效。1. 基礎概念張量Torch中一切皆為張量…

apache cgi測試

test.cgi #!/bin/sh echo "Content-type: text/html" echo "" echo "<h1>Hello from a Mac CGI script!</h1>" echo "<p>Current time is: $(date)</p>"?% 放置目錄 /opt/homebrew/Cellar/mapserver/8.4.0_1…

力扣 30 天 JavaScript 挑戰 第二題筆記

這道題是涉及知識–閉包 1. 閉包定義以及相關知識點 官方定義為&#xff1a;在 JavaScript 中&#xff0c;函數具有對在相同作用域以及任何外部作用域中聲明的所有變量的引用。這些作用域被稱為函數的 詞法環境。函數與其環境的組合被稱為 閉包。 簡單理解&#xff1a;內層函數…

OpenAI GPT-5 深度解析:API Key定價與ChatGPT(Free, Plus, Pro)用戶的區別

前言&#xff1a;兩年等待&#xff0c;只為這一躍 在科技圈長達兩年的屏息期待與無盡猜想之后&#xff0c;2025年8月8日北京時間凌晨&#xff0c;OpenAI終于揭開了其新一代旗艦模型——GPT-5的神秘面紗。這不僅僅是一次常規的產品迭代&#xff0c;更被整個行業視為一塊試金石&a…

ClickHouse集群部署實踐---3分片2副本集群

ClickHouse集群部署實踐—3分片2副本集群 未完待續。。。 喜歡的先點贊收藏&#xff01;&#xff01; 由于我們準備部署的是3分片2副本的集群&#xff0c;現在來解釋一下配置參數的意思&#xff1a; shard標簽代表分片的意思&#xff0c;如上圖我們有3個分片&#xff0c;clickh…

Unity_VR_Pico開發手冊

文章目錄一、配置開發環境1.下載PICO Unity Integration SDK2.安裝 Unity 編輯器&#xff08;添加安卓開發平臺模塊&#xff09;3.導入下載的SDK4.項目配置和切換開發平臺5.導入 XR Interaction Toolkit6.安裝 Universal RP(通用渲染管線)并設置 (選做)二、調試環境搭建&#x…

Linux系統之Docker命令與鏡像、容器管理

目錄 一、 Docker命令 docker命令幫助 docker常用子命令&#xff08;必須背會&#xff09; docker管理子命令(暫時不需要) swarm集群管理子命令&#xff08;不需要&#xff09; docker容器管理子命令&#xff08;必須背會&#xff09; docker全局選項 二、 docker鏡像管…