抽象工廠設計模式 Abstract Factory

抽象工廠

抽象工廠設計模式是一種創建模式,它提供了一個用于創建相關或從屬對象族的接口,而無需指定其具體類。
它在以下情況下特別有用:
您需要創建必須一起使用并且是一致系列的一部分的對象(例如,按鈕、復選框和菜單等 GUI 元素)。
您的系統必須支持多種配置、環境或產品變體(例如,淺色與深色主題、Windows 與 macOS 外觀)。

您希望在相關對象之間強制保持一致性,確保它們都是從同一個工廠創建的。
抽象工廠模式將 對象創建封裝到工廠接口中。

每個具體工廠實現接口并生成一組完整的相關對象。這可確保您的代碼保持可擴展、一致并與特定產品實現松散耦合。
讓我們通過一個真實世界的示例,看看如何應用抽象工廠模式來構建一個靈活、可維護的系統,并且能夠在沒有條件邏輯的情況下支持多個可互換的產品系列。

問題:特定于平臺的 UI
假設你正在構建一個必須同時支持 Windows 和 macOS 的跨平臺桌面應用程序。

為了提供良好的用戶體驗,您的應用程序應 為每個作系統呈現具有本機外觀的 UI 組件,例如:

按鈕
復選框
文本字段
菜單
樸素實現:條件 UI 組件實例化
在第一次嘗試中,您可以實現特定于平臺的 UI 組件,如下所示:
Windows UI 元素

??public?class?WindowsButton?implements?Button?{@Overridepublic?void?paint()?{System.out.println("Painting?a?Windows-style?button.");}@Overridepublic?void?onClick()?{System.out.println("Windows?button?clicked.");}
}public?class?WindowsCheckbox?implements?Checkbox?{@Overridepublic?void?paint()?{System.out.println("Painting?a?Windows-style?checkbox.");}@Overridepublic?void?onSelect()?{System.out.println("Windows?checkbox?selected.");}
}

MacOS UI元素

public?class?MacOSButton?implements?Button?{@Overridepublic?void?paint()?{System.out.println("Painting?a?macOS-style?button.");}@Overridepublic?void?onClick()?{System.out.println("MacOS?button?clicked.");}
}public?class?MacOSCheckbox?implements?Checkbox?{@Overridepublic?void?paint()?{System.out.println("Painting?a?macOS-style?checkbox.");}@Overridepublic?void?onSelect()?{System.out.println("MacOS?checkbox?selected.");}
}

然后,在應用程序邏輯中,您最終會執行以下作:

public?class?App?{public?static?void?main(String[]?args)?{String?os?=?System.getProperty("os.name");if?(os.contains("Windows"))?{WindowsButton?button?=?new?WindowsButton();WindowsCheckbox?checkbox?=?new?WindowsCheckbox();button.paint();checkbox.paint();}?else?if?(os.contains("Mac"))?{MacOSButton?button?=?new?MacOSButton();MacOSCheckbox?checkbox?=?new?MacOSCheckbox();button.paint();checkbox.paint();}}
}

為什么這種方法會失敗
雖然此設置適用于兩個平臺上的兩個 UI 組件,但隨著應用的增長,它很快就會成為一場噩夢。

  1. 1. 與混凝土類緊密耦合
    您的主應用程序邏輯與特定于平臺的類 (, , 等) 緊密綁定。這意味著無論在何處創建 UI 組件,都必須手動檢查作系統。WindowsButtonMacOSCheckbox
  2. 2. 無抽象或多態性
    不能籠統地處理按鈕或復選框。沒有像或可以使用的通用界面 。ButtonCheckbox
  3. 3. 代碼重復和重復
    每個特定于平臺的塊都復制了類似的邏輯——實例化按鈕、復選框、菜單等。你將在整個代碼庫中重復此條件分支。
  4. 4. 可擴展性問題
    當您:

添加新平臺(例如 Linux)?

添加新組件(例如,、、)?TextFieldSliderMenuBar

您必須:

為每個平臺添加新的具體類

修改代碼中出現特定于平臺的邏輯的每個位置

破壞現有行為的風險

  1. 5. 違反開放/關閉原則
    任何新的變體都需要修改現有代碼。您的 UI 創建邏輯不開放擴展,但對重大更改非常開放。

我們真正需要什么
我們需要一種方法來:

按平臺對相關組件(按鈕、復選框等)進行分組

將特定于平臺的創建邏輯封裝到工廠中

以多態方式處理 UI 組件,無論平臺如何

輕松添加新的 UI 元素系列,而無需修改應用程序的核心邏輯

這就是抽象工廠模式的用武之地。

抽象工廠模式
抽象工廠模式提供了一個接口,用于創建相關或依賴對象的族,而無需指定其具體類。

在我們的例子中,我們想要創建一個 UI 組件系列(如 、 、 等),這些組件在不同平臺(例如 Windows 或 macOS)上的外觀和行為不同,但向應用程序公開相同的界面。ButtonCheckboxTextField

抽象工廠模式通過以下方式幫助我們實現這一目標:

定義抽象 UI 工廠接口(例如 GUIFactory)

為每個平臺實施一個具體工廠(例如, WindowsFactoryMacOSFactory)

為每種類型的組件公開一組一致的接口(例如,, ButtonCheckbox)

讓客戶端使用這些接口,而無需擔心特定于平臺的實現

類圖

?

  1. 1. 抽象工廠 (GUIFactory)
    定義用于 創建相關產品系列的通用接口。

通常包括工廠方法,如 、 、 等。createButton()createCheckbox()createTextField()

客戶端依靠此接口創建對象,而無需知道其具體類型。

  1. 2. 混凝土廠 (, WindowsFactoryMacOSFactory)
    實現抽象工廠接口。

創建 屬于特定系列或平臺的具體產品變型。

每個工廠都確保其生產的所有組件都是兼容的(即屬于同一平臺/主題)。

  1. 3. 抽象產品 (, ButtonCheckbox)
    為 一組相關組件定義接口或抽象類。

給定類型(例如,,)的所有產品變體都 將實現這些接口。WindowsButtonMacOSButton

  1. 4. 混凝土產品 (, WindowsButtonMacOSCheckbox)
    實現抽象產品接口。

包含 組件的特定于平臺的邏輯和外觀。

  1. 5. 客戶 (Application)
    使用抽象工廠和抽象產品接口。

完全不知道它正在使用的具體類——它只與工廠和產品接互。

可以通過更改出廠方式切換整個產品系列(例如,從 Windows 切換到 macOS),而無需接觸 UI 邏輯。

實現抽象工廠
讓我們實現一個系統,讓我們的應用程序可以為 Windows 和 macOS 生成具有本機外觀的 UI 組件(按鈕、復選框), 而無需硬編碼平臺檢查或復制邏輯。

  1. 1. 定義抽象產品接口
    我們首先定義客戶端使用的產品接口。

Button

public?interface?Button?{void?paint();void?onClick();
}

Checkbox

public?interface?Checkbox?{void?paint();void?onSelect();
}
  1. 2. 創建具體產品類
    這些實現特定于平臺的邏輯。

Windows 組件

public?class?WindowsButton?implements?Button?{@Overridepublic?void?paint()?{System.out.println("Painting?a?Windows-style?button.");}@Overridepublic?void?onClick()?{System.out.println("Windows?button?clicked.");}
}public?class?WindowsCheckbox?implements?Checkbox?{@Overridepublic?void?paint()?{System.out.println("Painting?a?Windows-style?checkbox.");}@Overridepublic?void?onSelect()?{System.out.println("Windows?checkbox?selected.");}
}

macOS 組件

public?class?WindowsCheckbox?implements?Checkbox?{@Overridepublic?void?paint()?{System.out.println("Painting?a?Windows-style?checkbox.");}@Overridepublic?void?onSelect()?{System.out.println("Windows?checkbox?selected.");}
}public?class?MacOSCheckbox?implements?Checkbox?{@Overridepublic?void?paint()?{System.out.println("Painting?a?macOS-style?checkbox.");}@Overridepublic?void?onSelect()?{System.out.println("MacOS?checkbox?selected.");}
}
  1. 3. 定義抽象工廠
    這是用于創建相關產品系列的界面。
public?interface?GUIFactory?{Button?createButton();Checkbox?createCheckbox();
}
  1. 4. 實施混凝土工廠
    每個工廠都會創建特定于平臺的組件變體。

WindowsFactory

public?class?WindowsFactory?implements?GUIFactory?{@Overridepublic?Button?createButton()?{return?new?WindowsButton();}@Overridepublic?Checkbox?createCheckbox()?{return?new?WindowsCheckbox();}
}

MacOSFactory

public?class?MacOSFactory?implements?GUIFactory?{@Overridepublic?Button?createButton()?{return?new?MacOSButton();}@Overridepublic?Checkbox?createCheckbox()?{return?new?MacOSCheckbox();}
}
  1. 5. 客戶端代碼 – 僅使用抽象接口
    客戶端代碼根據作系統選擇工廠,并使用它來創建 UI 組件。
public?class?Application?{private?final?Button?button;private?final?Checkbox?checkbox;public?Application(GUIFactory?factory)?{this.button?=?factory.createButton();this.checkbox?=?factory.createCheckbox();}public?void?renderUI()?{button.paint();checkbox.paint();}
}
  1. 6. 申請切入點

輸出(在 macOS 上)

Painting?a?macOS-style?button.
Painting?a?macOS-style?checkbox.

輸出(在 Windows 上)

Painting?a?Windows-style?button.
Painting?a?Windows-style?checkbox.

我們取得了什么成就
平臺獨立性:應用程序代碼從不引用特定于平臺的類
一致性:按鈕和復選框始終與所選作系統樣式匹配
開放/封閉原則:在不修改現有工廠或組件的情況下添加對 Linux 或 Android 的支持
可測試性和靈活性:工廠可以輕松更換以進行測試或主題
其他資料:

https://pan.baidu.com/s/1c1oQItiA7nZxz8Rnl3STpw?pwd=yftc
https://pan.quark.cn/s/dec9e4868381

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

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

相關文章

WSL 下的虛擬網卡配置

第一部分:Windows 虛擬網卡創建指南 1. 原理 在 Windows 里,“虛擬網卡”本質是由網絡驅動在系統網絡棧中創建的一個 軟件網卡接口。它的作用和物理網卡類似,只不過不直接連接到物理硬件,而是通過內核網絡驅動與宿主機網絡進行交換…

Dify web前端源碼本地部署詳細教程

目錄 1. 先啟動API 2. 啟動worker服務 3. 啟動web 4. 訪問登陸地址 在前面的文章中,Dify源碼部署,搭建二次開發環境(一) 已經記錄了如何在本地啟動API、work、中間件。在本篇文章中,將概述如何啟動dify web源碼項…

CVPR 2025|英偉達聯合牛津大學提出面向3D醫學成像的統一分割基礎模型

在 2D 自然圖像和視頻的交互式分割領域,基礎模型已引發廣泛關注,這也促使人們開始構建用于醫學成像的 3D 基礎模型。然而,3D 醫學成像存在的領域差異以及臨床應用場景,要求開發一種有別于現有 2D 解決方案的專用模型。具體而言&am…

解決“Win7共享文件夾其他電腦網絡無法發現共享電腦名稱”的問題

要讓運行 Windows 7 的電腦被局域網中其他設備(包括另一臺電腦、手機、NAS 等)“發現”,必須同時滿足三個條件: 網絡發現功能已啟用;對應的后臺服務已啟動;防火墻規則放行。 下面給出最簡、最穩妥的 3 步設…

Python pyzmq 庫詳解:從入門到高性能分布式通信

一、前言 在現代軟件開發中,進程間通信(IPC)與分布式系統通信已經成為基礎能力。無論是構建一個微服務架構的后端,還是實現大規模并行計算任務,如何讓不同的進程或節點之間高效地傳遞消息,都是核心問題。 傳…

CentOS 7更換國內鏡像源

第一步:檢查系統版本 在修改任何配置之前,先確定你的 CentOS 版本,因為不同版本的鏡像源配置文件不同。 cat /etc/redhat-release這個命令會顯示你的 CentOS 版本信息,例如 CentOS Linux release 7.9.2009 (Core)。從你的錯誤日志…

詳解 doclayout_yolo:Python 文檔布局檢測

目錄一、doclayout_yolo 核心功能二、安裝方法1. 直接安裝2. 通過 PDF-Extract-Kit 安裝三、使用示例1. 快速體驗(HuggingFace Demo)2. 本地推理代碼3. 批量處理四、技術亮點五、應用場景六、其他說明1.相關資源2. 注意事項doclayout_yolo 是一個基于 Y…

貓頭虎AI分享|一款Coze、Dify類開源AI應用超級智能體Agent快速構建工具:FastbuildAI

貓頭虎AI分享|一款 Coze、Dify 類開源 AI 應用超級智能體快速構建工具:FastbuildAI 區別在于它的易用度和商業閉環功能 摘要:FastbuildAI 是一個開源的 AI 應用“快速構建 商業化閉環”工具。它讓個人開發者與小團隊用 可視化 零代碼 的方…

GitLab 安全漏洞 CVE-2025-6186 解決方案

本分分享極狐GitLab 補丁版本 18.2.2, 18.1.4, 18.0.6 的詳細內容。這幾個版本包含重要的缺陷和安全修復代碼,我們強烈建議所有私有化部署用戶應該立即升級到上述的某一個版本。對于極狐GitLab SaaS,技術團隊已經進行了升級,無需用戶采取任何…

【K8s】harbor安裝與推送鏡像

引言 在開發中,先推送鏡像到docker,然后直接在docker運行。但是在K8S中,需要動態創建或者分配機器,這里需要將鏡像推送到harbor倉庫,然后再從倉庫拉取到每臺集群機器。 docker安裝harbor:https://learnku…

FPGA讀取AHT20溫濕度模塊思路及實現,包含遇到的問題(IIC協議)

一.閱讀官方手冊 手冊在下方網址下載,該模塊在各個網店平臺均有銷售 百度網盤 請輸入提取碼 手冊重點關注IIC地址(讀地址0x71,寫地址0x70)、IIC命令和讀寫數據邏輯,手冊寫的比較簡單(感覺很多細節沒到位…

項目會議怎么開才有效

要提高項目會議的有效性,需要做到以下幾點:明確會議目的、制定具體的會議議程、合理控制會議時長、提前準備會議資料、選擇合適的參會人員、設定清晰的會議目標、確保會議有決策和行動方案、會后及時跟進與落實。其中,明確會議目的尤為重要。…

計算機視覺第一課opencv(二)保姆級教

目錄 簡介 一、邊界填充 1.函數說明 2.案例分析 二、圖像運算 1.號運算 2.cv2.add()函數 3.圖像加權運算 三、閾值處理 四、圖像平滑處理 1.椒鹽噪聲 2.均值濾波(Mean Filtering) 3.方框濾波 4. 高斯濾波(Gaussian Filtering&am…

母豬姿態轉換行為識別:計算機視覺與行為識別模型調優指南

> 在現代智能化養殖中,母豬姿態識別是健康監測的關鍵技術。本文將帶你從0到1構建高精度母豬姿態識別系統,準確率可達95%以上! ## 一、為什么母豬姿態識別如此重要? 母豬的行為姿態是其健康狀況的重要指標: - **站立姿態**:可能表示發情期或進食需求 - **側臥姿態**:…

循序漸進學 Spring (下):從注解、AOP到底層原理與整合實戰

文章目錄7. 自動裝配 (Autowiring)7.1 XML 自動裝配7.2 使用注解實現自動裝配Autowired vs Resource8. 使用注解開發(完全體)8.1 定義 Bean (Component 及其衍生注解)8.2 注入屬性 (Value)8.3 注入對象8.4 定義作用域 (Scope)8.5 小結:XML vs…

C#WPF實戰出真汁06--【系統設置】--餐桌類型設置

1、系統設置的基本概念系統設置是用于配置和管理餐桌類型和菜品類型,是維護整個系統的基礎數據。通過系統設置,用戶可以調整餐桌類型的添加,刪除,編輯,分頁,查詢,重置,列表&#xff…

旋鈕鍵盤項目---foc講解(閉環位置控制)

hello,周六休息了一天,出去打本了。趁著夜色,花費了幾個小時,也是將閉環代碼寫完,參考了燈哥的思路。接下來介紹一下我的整個流程: 一、閉環位置控制思路: 其實懂得了開環,那么閉環…

為什么有些相機“即插即用”,而有些則需要采集卡?

在工業生產中,工業相機是“眼睛”,它幫助我們看到世界,但你知道嗎?不同的工業相機接口就像不同的“通道”,有些“通道”直接就能與計算機連接,而有些則需要一個額外的小配件——圖像采集卡。那么&#xff0…

【計算機網絡 | 第7篇】物理層基本概念

文章目錄物理層基本概念及數據通信系統解析一、物理層的核心定位🥝二、物理層的功能🧾三、數據通信系統的模型🐦?🔥(一)源系統(二)傳輸系統(三)目的系統四、…

一般情況下,python函數都會返回對象,但有時只調用一個函數,這是在修改這個信息

class Model:def __init__(self):self.training Truedef eval(self):self.training Falsereturn Nonem Model() print(m.training) # True m.eval() # 返回 None print(m.training) # False,模型內部狀態已改變m.eval()是在修改m的…