設計模式-工廠模式(Factory Pattern)

一、工廠模式說明

????????工廠模式是一種創建型設計模式,它提供了一種將對象的創建與使用分離的方式。工廠模式通過引入一個公共的接口來創建對象,而不是通過直接調用構造函數來創建對象。這樣做的好處是使得代碼更加靈活,更容易維護和擴展。

????????工廠模式通常包含以下幾個角色:

????????產品(Product): 產品是工廠模式所創建的對象。它可以是一個接口、抽象類或者具體類,用來描述工廠創建的對象所具有的特性和行為。

????????工廠接口(Factory Interface): 工廠接口是用來創建產品對象的接口,它定義了一個或多個工廠方法用來創建產品。通常情況下,工廠接口是一個抽象類或者接口,其中的工廠方法可以是抽象方法或者默認實現方法。

????????具體工廠(Concrete Factory): 具體工廠是工廠模式的實現者,它實現了工廠接口,負責創建具體的產品對象。每個具體工廠類通常都與一個特定的產品相關聯,用來創建該產品的實例。

????????客戶端(Client): 客戶端是使用工廠模式的地方,它通過工廠接口來創建產品對象,而不需要知道具體的產品類。客戶端通常只與工廠接口和產品接口交互,而不直接依賴具體的產品類。

二、工廠模式應用

????????在實際應用中的例子時,有幾個常見的場景:

????????數據庫連接池: 在大多數現代應用程序中,需要頻繁地與數據庫進行交互。為了提高性能和效率,通常會使用數據庫連接池。連接池是一組預先創建的數據庫連接,可以在需要時重新使用。工廠模式可用于創建這些數據庫連接,以便統一管理連接的創建和銷毀。例如,可以使用工廠方法模式創建不同類型的數據庫連接對象,如 MySQL 連接、PostgreSQL 連接等。

????????日志記錄器: 許多應用程序需要記錄事件和錯誤信息以便后期分析和調試。日志記錄器是用于記錄這些信息的工具。工廠模式可用于創建不同類型的日志記錄器,如文件日志記錄器、數據庫日志記錄器、控制臺日志記錄器等。根據應用程序的需求,可以選擇合適的日志記錄器類型。例如,可以使用抽象工廠模式來創建不同類型的日志記錄器對象,并使用配置文件或其他參數來確定要創建的日志記錄器類型。

????????UI控件庫: 在圖形用戶界面(GUI)應用程序中,UI控件庫用于創建和管理各種用戶界面元素,如按鈕、文本框、標簽等。工廠模式可用于創建這些UI控件。例如,可以使用簡單工廠模式創建不同類型的UI控件對象,并提供統一的接口來訪問這些控件。這樣可以降低客戶端代碼與具體控件實現之間的耦合,并提高代碼的靈活性和可維護性。

????????加密算法庫: 在安全領域中,加密算法是非常重要的組成部分。工廠模式可用于創建不同類型的加密算法對象,如對稱加密算法、非對稱加密算法等。例如,可以使用工廠方法模式創建不同類型的加密算法對象,并提供統一的接口來加密和解密數據。這樣可以方便地切換和使用不同類型的加密算法,而不影響客戶端代碼。

????????游戲開發: 在游戲開發中,經常需要創建各種游戲對象,如角色、道具、怪物等。工廠模式可用于創建這些游戲對象。例如,可以使用工廠方法模式創建不同類型的游戲對象,并提供統一的接口來處理游戲邏輯。這樣可以方便地擴展和修改游戲中的對象,而不需要修改客戶端代碼。

三、 工廠模式的實現

(一) 簡單工廠模式

????????簡單工廠模式(Simple Factory Pattern)是一種創建型設計模式,它提供了一個專門的工廠類用于創建對象,而不需要將對象的創建邏輯暴露給客戶端。簡單工廠模式通過將對象的創建過程封裝在工廠類中,使得客戶端無需知道具體的實例化邏輯,只需要通過工廠類來獲取所需的對象。

????????簡單工廠模式由三個主要組成部分構成:

????????工廠類(Factory Class):工廠類負責創建對象的實例。通常包含一個靜態方法或成員方法,根據客戶端的請求創建并返回具體的對象實例。客戶端通過調用工廠類的方法獲取所需的對象。

????????抽象產品類(Abstract Product Class):抽象產品類定義了所創建的對象的通用接口,客戶端通過該接口與具體產品進行交互。工廠類負責創建的對象都是抽象產品類的子類對象。

????????具體產品類(Concrete Product Class):具體產品類是抽象產品類的具體實現,它實現了抽象產品類定義的接口,并提供了具體的功能和行為。

#include <iostream>
#include <memory>// 抽象產品類
class Product {
public:virtual void showInfo() = 0;virtual ~Product() {}
};// 具體產品接口1:顏色屬性 <- 這邊是為了實現 接口隔離原則 
class Colorable {
public:virtual void setColor(const std::string& color) = 0;virtual std::string getColor() const = 0;virtual ~Colorable() {}
};// 具體產品類:電子產品
class ElectronicProduct : public Product {
public:void showInfo() override {std::cout << "Electronic Product: Smart Phone\n";}
};// 具體產品類:服裝
class ClothingProduct : public Product, public Colorable {
private:std::string color;
public:void showInfo() override {std::cout << "Clothing Product: T-Shirt\n";}void setColor(const std::string& color) override {this->color = color;}std::string getColor() const override {return color;}
};// 具體產品類:食品
class FoodProduct : public Product {
public:void showInfo() override {std::cout << "Food Product: Chocolate\n";}
};// 簡單工廠類
class ProductFactory {
public:// 根據傳入的參數創建不同類型的產品對象std::unique_ptr<Product> createProduct(char type) {switch (type) {case 'E':return std::make_unique<ElectronicProduct>();case 'C':return std::make_unique<ClothingProduct>();case 'F':return std::make_unique<FoodProduct>();default:std::cerr << "Invalid product type\n";return nullptr;}}
};int main() {// 使用簡單工廠創建不同類型的商品對象ProductFactory factory;std::unique_ptr<Product> product1 = factory.createProduct('E');if (product1) {product1->showInfo();}std::unique_ptr<Product> product2 = factory.createProduct('C');if (product2) {product2->showInfo();Colorable* colorableProduct = dynamic_cast<Colorable*>(product2.get());if (colorableProduct) {colorableProduct->setColor("Red");std::cout << "Color: " << colorableProduct->getColor() << std::endl;}}std::unique_ptr<Product> product3 = factory.createProduct('F');if (product3) {product3->showInfo();}return 0;
}

(二) 工廠方法模式

????????工廠方法模式(Factory Method Pattern)是一種創建型設計模式,它定義了一個用于創建對象的接口,但是將具體對象的創建延遲到了子類中。這樣,工廠方法模式允許一個類的實例化延遲到子類中,從而使得一個類的實例化與子類的具體實現解耦。

????????工廠方法模式由四個主要組成部分構成:

????????抽象產品類(Abstract Product Class):定義了工廠方法所創建的對象的接口,客戶端通過該接口與具體產品進行交互。

????????具體產品類(Concrete Product Class):具體產品類是抽象產品類的實現,它定義了具體產品的屬性和行為。

????????抽象工廠類(Abstract Factory Class):抽象工廠類定義了一個抽象的工廠方法,該方法返回一個抽象產品類的實例。該類可以是抽象類或接口。

????????具體工廠類(Concrete Factory Class):具體工廠類是抽象工廠類的實現,它實現了抽象工廠類定義的工廠方法,負責創建具體的產品對象。

#include <iostream>
#include <memory>// 抽象產品類
class Product {
public:virtual void showInfo() = 0;virtual ~Product() {}
};// 具體產品類:電子產品
class ElectronicProduct : public Product {
public:void showInfo() override {std::cout << "Electronic Product: Smart Phone\n";}
};// 具體產品類:服裝
class ClothingProduct : public Product {
public:void showInfo() override {std::cout << "Clothing Product: T-Shirt\n";}
};// 具體產品類:食品
class FoodProduct : public Product {
public:void showInfo() override {std::cout << "Food Product: Chocolate\n";}
};// 抽象工廠類
class ProductFactory {
public:virtual std::unique_ptr<Product> createProduct() = 0;virtual ~ProductFactory() {}
};// 具體工廠類:電子產品工廠
class ElectronicProductFactory : public ProductFactory {
public:std::unique_ptr<Product> createProduct() override {return std::make_unique<ElectronicProduct>();}
};// 具體工廠類:服裝工廠
class ClothingProductFactory : public ProductFactory {
public:std::unique_ptr<Product> createProduct() override {return std::make_unique<ClothingProduct>();}
};// 具體工廠類:食品工廠
class FoodProductFactory : public ProductFactory {
public:std::unique_ptr<Product> createProduct() override {return std::make_unique<FoodProduct>();}
};int main() {// 使用具體工廠類來創建產品對象std::unique_ptr<ProductFactory> electronicFactory = std::make_unique<ElectronicProductFactory>();std::unique_ptr<Product> product1 = electronicFactory->createProduct();product1->showInfo();std::unique_ptr<ProductFactory> clothingFactory = std::make_unique<ClothingProductFactory>();std::unique_ptr<Product> product2 = clothingFactory->createProduct();product2->showInfo();std::unique_ptr<ProductFactory> foodFactory = std::make_unique<FoodProductFactory>();std::unique_ptr<Product> product3 = foodFactory->createProduct();product3->showInfo();return 0;
}

(三) 抽象工廠模式

????????抽象工廠模式(Abstract Factory Pattern)是一種創建型設計模式,它提供了一個接口用于創建一系列相關或相互依賴的對象,而無需指定它們的具體類。抽象工廠模式通過引入抽象工廠類和具體工廠類來實現對象的創建,使得客戶端可以從抽象工廠類中獲取具體工廠類的實例,進而創建所需的產品對象。

????????抽象工廠模式由四個主要組成部分構成:

????????抽象產品類(Abstract Product Class):定義了工廠方法所創建的對象的接口,客戶端通過該接口與具體產品進行交互。

????????具體產品類(Concrete Product Class):具體產品類是抽象產品類的實現,它定義了具體產品的屬性和行為。

????????抽象工廠類(Abstract Factory Class):抽象工廠類定義了一個抽象的工廠方法,該方法返回一個抽象產品類的實例。抽象工廠類可以是一個接口或者抽象類。

????????具體工廠類(Concrete Factory Class):具體工廠類是抽象工廠類的實現,它實現了抽象工廠類定義的工廠方法,并負責創建具體的產品對象。

#include <iostream>
#include <memory>// 抽象產品類
class ElectronicProduct {
public:virtual void showInfo() = 0;virtual ~ElectronicProduct() {}
};class ClothingProduct {
public:virtual void showInfo() = 0;virtual ~ClothingProduct() {}
};// 具體產品類:手機
class SmartPhone : public ElectronicProduct {
public:void showInfo() override {std::cout << "Smart Phone\n";}
};// 具體產品類:T恤
class TShirt : public ClothingProduct {
public:void showInfo() override {std::cout << "T-Shirt\n";}
};// 抽象工廠類
class AbstractFactory {
public:virtual std::unique_ptr<ElectronicProduct> createElectronicProduct() = 0;virtual std::unique_ptr<ClothingProduct> createClothingProduct() = 0;virtual ~AbstractFactory() {}
};// 具體工廠類:電子產品工廠
class ElectronicFactory : public AbstractFactory {
public:std::unique_ptr<ElectronicProduct> createElectronicProduct() override {return std::make_unique<SmartPhone>();}std::unique_ptr<ClothingProduct> createClothingProduct() override {// 在這個工廠中,我們無法創建服裝產品,因此返回 nullptrreturn nullptr;}
};// 具體工廠類:服裝工廠
class ClothingFactory : public AbstractFactory {
public:std::unique_ptr<ElectronicProduct> createElectronicProduct() override {// 在這個工廠中,我們無法創建電子產品,因此返回 nullptrreturn nullptr;}std::unique_ptr<ClothingProduct> createClothingProduct() override {return std::make_unique<TShirt>();}
};int main() {// 創建電子產品工廠并使用std::unique_ptr<AbstractFactory> electronicFactory = std::make_unique<ElectronicFactory>();std::unique_ptr<ElectronicProduct> electronicProduct = electronicFactory->createElectronicProduct();if (electronicProduct) {electronicProduct->showInfo();}// 創建服裝工廠并使用std::unique_ptr<AbstractFactory> clothingFactory = std::make_unique<ClothingFactory>();std::unique_ptr<ClothingProduct> clothingProduct = clothingFactory->createClothingProduct();if (clothingProduct) {clothingProduct->showInfo();}return 0;
}

四、工廠模式總結

工廠模式類型

優點

缺點

適用場景

簡單工廠模式

(Simple Factory Pattern)

- 實現簡單易懂

- 將對象創建和使用解耦

- 違反開閉原則

- 工廠類集中了所有產品的創建邏輯

- 產品較少

- 產品不經常變化

工廠方法模式

(Factory Method Pattern)

- 符合開閉原則

- 延遲對象的創建

- 增加靈活性

- 每次新增產品都需要編寫一個具體工廠類

- 產品具有相同接口

- 創建邏輯相對復雜的情況

抽象工廠模式

(Abstract Factory Pattern)

- 將對象創建和使用解耦

- 符合開閉原則

- 新增產品族比較困難

- 需要修改抽象工廠接口及實現類

- 創建一系列相關產品對象

- 保證產品族一致性

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

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

相關文章

第3部分 原理篇2去中心化數字身份標識符(DID)(2)

3.2.2. DID相關概念 3.2.2.1. 去中心化標識符 (Decentralized identifier&#xff0c;DID) 本聰老師&#xff1a;DID有兩個含義&#xff0c;一是Decentralized identity&#xff0c;就是去中心化身份&#xff0c;是廣泛意義的DID。另外一個是Decentralized identifier&#xf…

Web性能優化-瀏覽器工作原理-MDN文檔學習筆記

瀏覽器工作原理 查看更多學習筆記&#xff1a;GitHub&#xff1a;LoveEmiliaForever MDN中文官網 導航 導航是加載 web 頁面的第一步&#xff1a;輸入 URL、點擊一個鏈接、提交表單等等 DNS查詢 導航的第一步是要去尋找頁面資源的位置 例如訪問https://example.com&#x…

如何解決DNS解析錯誤故障

DNS解析錯誤會導致將一個域名解析為錯誤的IP地址&#xff0c;或者根本無法確定某個域名對應的IP地址&#xff0c;從而無法通過域名訪問相應的站點&#xff0c;形成DNS解析故障。最常見的癥狀是訪問站點對應的IP地址沒有問題&#xff0c;但訪問其域名時卻出現錯誤。 DNS解析異常…

qt-動畫圓圈等待-LED數字

qt-動畫圓圈等待-LED數字 一、演示效果二、關鍵程序三、下載鏈接 一、演示效果 二、關鍵程序 #include "LedNumber.h" #include <QLabel>LEDNumber::LEDNumber(QWidget *parent) : QWidget(parent) {//設置默認寬高比setScale((float)0.6);//設置默認背景色se…

【深入了解TensorFlow】TensorFlow的安裝與配置

【深入了解TensorFlow】TensorFlow的安裝與配置 TensorFlow的安裝與配置準備就緒:開始前的準備工作1. 確定您的硬件和操作系統2. 選擇安裝方式3. 創建虛擬環境(可選)安裝TensorFlow使用pip安裝使用conda安裝從源代碼編譯安裝配置TensorFlow導入TensorFlow模塊檢查安裝是否成…

Oracle 表被刪除或重命名后賬戶間的授權與同義詞關系

Oracle 表被刪除或重命名后賬戶間的授權與同義詞關系 情景一、 當數據表刪除后 數據表被刪除后&#xff0c;同義詞還是存在的&#xff0c;可以查看當前用戶下查看同義詞&#xff1a; -- 查看當前用戶下的同義詞 select * from user_synonyms但授權關系不在了&#xff0c;若重…

10 個 Linux 中超方便的 Bash 別名

1、 你有幾次遇到需要解壓 .tar 文件但無法記住所需的確切參數&#xff1f;別名可以幫助你&#xff01;只需將以下內容添加到 .bash_profile 中&#xff0c;然后使用 untar FileName 解壓縮任何 .tar 文件。 alias untartar -zxvf 2、 下載文件時&#xff0c;如果出現問題想要…

websocket與Socket的區別

概念講解 網絡&#xff1a;通俗意義上&#xff0c;也就是連接兩臺計算器 五層網絡模型&#xff1a;應用層、傳輸層、網絡層、數據鏈路層、物理層 應用層 (application layer)&#xff1a;直接為應用進程提供服務。應用層協議定義的是應用進程間通訊和交互的規則&#xff0c;不…

明明正常,卻不停return

明明正常&#xff0c;卻不停return if(!is); { return ; } 熬人

應急響應速查

最重要的&#xff1a;我是誰&#xff1f;我在哪&#xff1f;別人怎么進來的&#xff1f;我就是這個被挖礦被勒索的電腦。 分析項 &#xff1a; 一、了解大概的被入侵系統情況&#xff1a; 發現時間&#xff1f;怎么發現的&#xff1f;這臺機器有沒有人運維&#xff1f;平時還…

排序第三篇 直接插入排序

插入排序的基本思想是&#xff1a; 每次將一個待排序的記錄按其關鍵字的大小插入到前面已排好序的文件中的適當位置&#xff0c; 直到全部記錄插入完為止。 一 簡介 插入排序可分為2類 本文介紹 直接插入排序 它的基本操作是&#xff1a; 假設待排充序的記錄存儲在數組 R[1……

電路設計(27)——交通信號燈的multisim仿真

1.功能要求 使用數字芯片設計一款交通信號燈&#xff0c;使得&#xff1a; 主干道的綠燈時間為60S&#xff0c;紅燈時間為45S 次干道的紅燈時間為60S&#xff0c;綠燈時間為45S 主、次干道&#xff0c;綠燈的最后5S內&#xff0c;黃燈閃爍 使用數碼管顯示各自的倒計時時間。 按…

JavaScript 數組、遍歷

數組 多維數組&#xff1a;數組里面嵌套 一層數組為二維數組。一維數組的使用頻率是最高的。 如果數組訪問越界會返回undefined。 數組遍歷 數組方法Array.isArray() 這個方法可以去判定一個內容是否是數組。

AndroidStudio 2024-2-21 Win10/11最新安裝配置(Kotlin快速構建配置,gradle鏡像源)

AndroidStudio 2024 Win10/11最新安裝配置 教程目的&#xff1a; (從安裝到卸載) &#xff0c;針對Kotlin開發配置&#xff0c;gradle-8.2-src/bin下載慢&#xff0c;以及Kotlin構建慢的解決 好久沒玩AS了,下載發現裝個AS很麻煩,就覺得有必要出個教程了(就是記錄一下:嘻嘻) 因…

把一個對象變成可迭代對象的兩種方法,使用Symbol.iterator 和生成器Generator

方法一&#xff1a;自定義Symbol.iterator屬性 如果對象擁有[Symbol.iterator] 方法&#xff0c;改方法返回一個迭代器對象&#xff0c;就可以稱之為可迭代對象&#xff0c;注意迭代器是一個有 next 方法的對象 步驟如下 實現一個Symbol.iterator 鍵值是一個函數&#xff0c;…

java 時間格式 YYYY 于yyyy的區別

java formatDate 時間時&#xff0c;經常需要輸入格式比如 YYYYMMDD,yyyyMMdd 這兩個是有區別的 具體每個參數可以看下面

igolang學習1,dea的golang-1.22.0

參考&#xff1a;使用IDEA配置GO的開發環境備忘錄-CSDN博客 1.下載All releases - The Go Programming Language (google.cn) 2.直接next 3.window環境變量配置 4.idea的go插件安裝 5.新建go項目找不到jdk解決 https://blog.csdn.net/ouyang111222/article/details/1361657…

代碼隨想錄算法訓練營第40天| 343. 整數拆分、96.不同的二叉搜索樹

343. 整數拆分 完成 思路&#xff1a; dp數組存放正整數i拆分后的乘積最大值&#xff1b;i可以拆分為j和i-j&#xff0c;也可以是j和dp[i-j]。 代碼 class Solution {public int integerBreak(int n) {int[] dp new int[n1];dp[2] 1;// 推導i的拆分乘積最大值for (int i …

【js】無限虛擬列表的原理及實現

什么是虛擬列表 虛擬列表是長列表按需顯示思路的一種實現&#xff0c;即虛擬列表是一種根據滾動容器元素的可視區域來渲染長列表數據中某一個部分數據的技術。 簡而言之&#xff0c;虛擬列表指的就是「可視區域渲染」的列表。有三個概念需要了解一下&#xff1a; 視口容器元…

【linux】linux查看某個已經啟動進程的環境變量及命令行信息 /proc/${pid}/environ cmdline

隨便找一個進程 yeqiangyeqiang-MS-7B23:~$ ps aux | grep Vir yeqiang 3538 0.4 0.6 1797056 210332 ? Sl 08:38 0:06 /usr/lib/virtualbox/VirtualBox 查看命令行 yeqiangyeqiang-MS-7B23:~$ strings /proc/3538/cmdline /usr/lib/virtualbox/VirtualBox …