【C++】簡單工廠模式/工廠方法模式/抽象工廠模式對比

目錄

  • 一、簡單工廠模式(Simple Factory Pattern)
  • 二、工廠方法模式(Factory Method Pattern)
  • 三、抽象工廠模式(Abstract Factory Pattern)
  • 四、三者對比總結
  • 五、選擇建議
    • 如果這篇文章對你有所幫助,渴望獲得你的一個點贊!

抽象工廠模式、簡單工廠模式和工廠方法模式都是創建型設計模式,它們的核心目的都是將對象的創建和使用分離,但在實現復雜度、靈活性和應用場景上存在顯著差異。以下從定義、結構、適用場景和代碼示例四個方面進行對比分析:

一、簡單工廠模式(Simple Factory Pattern)

定義與結構

  • 定義:簡單工廠模式是一種創建對象的方式,它將對象的創建邏輯封裝在一個工廠類中,通過傳入參數決定創建哪種產品。
  • 核心角色:
    • 工廠類(Factory):負責創建產品的靜態方法。
    • 抽象產品(Product):定義產品的接口。
    • 具體產品(ConcreteProduct):實現抽象產品接口。

適用場景

  • 產品種類較少且創建邏輯簡單。
  • 客戶端只需通過參數指定需要創建的產品,不關心創建細節。

代碼示例

// 抽象產品
class Shape {
public:virtual void draw() = 0;virtual ~Shape() = default;
};// 具體產品
class Circle : public Shape {
public:void draw() override { std::cout << "Circle::draw()" << std::endl; }
};class Rectangle : public Shape {
public:void draw() override { std::cout << "Rectangle::draw()" << std::endl; }
};// 簡單工廠
class ShapeFactory {
public:static std::unique_ptr<Shape> createShape(const std::string& type) {if (type == "circle") return std::make_unique<Circle>();if (type == "rectangle") return std::make_unique<Rectangle>();return nullptr; // 錯誤處理}
};// 客戶端使用
void client() {auto circle = ShapeFactory::createShape("circle");circle->draw(); // 輸出: Circle::draw()
}

特點

  • 優點:實現簡單,將對象創建集中管理。
  • 缺點:工廠類職責過重,新增產品需修改工廠類,違反開閉原則。

二、工廠方法模式(Factory Method Pattern)

定義與結構

  • 定義:工廠方法模式定義創建對象的接口,讓子類決定實例化哪個類。工廠方法將產品的創建延遲到子類。
  • 核心角色:
    • 抽象工廠(AbstractFactory):聲明工廠方法,返回抽象產品。
    • 具體工廠(ConcreteFactory):實現工廠方法,創建具體產品。
    • 抽象產品(Product):定義產品的接口。
    • 具體產品(ConcreteProduct):實現抽象產品接口。

適用場景

  • 當一個類不知道它所需要的對象的類時(如框架設計)。
  • 當一個類希望由其子類來指定創建對象時。
  • 當類將創建對象的職責委托給多個子類中的某一個,并且希望在運行時動態指定時。

代碼示例

// 抽象產品
class Product {
public:virtual void operation() = 0;virtual ~Product() = default;
};// 具體產品
class ConcreteProductA : public Product {
public:void operation() override { std::cout << "ConcreteProductA::operation()" << std::endl; }
};class ConcreteProductB : public Product {
public:void operation() override { std::cout << "ConcreteProductB::operation()" << std::endl; }
};// 抽象工廠
class Factory {
public:virtual std::unique_ptr<Product> createProduct() = 0;virtual ~Factory() = default;
};// 具體工廠
class ConcreteFactoryA : public Factory {
public:std::unique_ptr<Product> createProduct() override {return std::make_unique<ConcreteProductA>();}
};class ConcreteFactoryB : public Factory {
public:std::unique_ptr<Product> createProduct() override {return std::make_unique<ConcreteProductB>();}
};// 客戶端使用
void client(Factory& factory) {auto product = factory.createProduct();product->operation();
}// 使用示例
int main() {ConcreteFactoryA factoryA;client(factoryA); // 輸出: ConcreteProductA::operation()ConcreteFactoryB factoryB;client(factoryB); // 輸出: ConcreteProductB::operation()
}

特點

  • 優點:符合開閉原則,新增產品只需添加新的具體工廠,無需修改抽象工廠和客戶端。
  • 缺點:工廠子類過多時會導致代碼復雜度增加。

三、抽象工廠模式(Abstract Factory Pattern)

定義與結構

  • 定義:抽象工廠模式提供一個創建一系列相關或相互依賴對象的接口,而無需指定它們具體的類。
  • 核心角色:
    • 抽象工廠(AbstractFactory):聲明創建多個抽象產品的方法。
    • 具體工廠(ConcreteFactory):實現抽象工廠的方法,創建一組具體產品。
    • 抽象產品族(AbstractProduct):定義多個產品的接口。
    • 具體產品(ConcreteProduct):實現抽象產品接口。

適用場景

  • 系統需要獨立于產品的創建、組合和表示時。
  • 系統需要使用多個產品族中的一個,且產品之間有依賴關系。
  • 需要動態切換產品系列時(如跨平臺 UI、主題系統)。

代碼示例

// 抽象產品A
class AbstractProductA {
public:virtual void operationA() = 0;virtual ~AbstractProductA() = default;
};// 具體產品A1
class ProductA1 : public AbstractProductA {
public:void operationA() override { std::cout << "ProductA1::operationA()" << std::endl; }
};// 具體產品A2
class ProductA2 : public AbstractProductA {
public:void operationA() override { std::cout << "ProductA2::operationA()" << std::endl; }
};// 抽象產品B
class AbstractProductB {
public:virtual void operationB() = 0;virtual ~AbstractProductB() = default;
};// 具體產品B1
class ProductB1 : public AbstractProductB {
public:void operationB() override { std::cout << "ProductB1::operationB()" << std::endl; }
};// 具體產品B2
class ProductB2 : public AbstractProductB {
public:void operationB() override { std::cout << "ProductB2::operationB()" << std::endl; }
};// 抽象工廠
class AbstractFactory {
public:virtual std::unique_ptr<AbstractProductA> createProductA() = 0;virtual std::unique_ptr<AbstractProductB> createProductB() = 0;virtual ~AbstractFactory() = default;
};// 具體工廠1
class ConcreteFactory1 : public AbstractFactory {
public:std::unique_ptr<AbstractProductA> createProductA() override {return std::make_unique<ProductA1>();}std::unique_ptr<AbstractProductB> createProductB() override {return std::make_unique<ProductB1>();}
};// 具體工廠2
class ConcreteFactory2 : public AbstractFactory {
public:std::unique_ptr<AbstractProductA> createProductA() override {return std::make_unique<ProductA2>();}std::unique_ptr<AbstractProductB> createProductB() override {return std::make_unique<ProductB2>();}
};// 客戶端使用
void client(AbstractFactory& factory) {auto productA = factory.createProductA();auto productB = factory.createProductB();productA->operationA();productB->operationB();
}// 使用示例
int main() {ConcreteFactory1 factory1;client(factory1); // 輸出: ProductA1::operationA() 和 ProductB1::operationB()ConcreteFactory2 factory2;client(factory2); // 輸出: ProductA2::operationA() 和 ProductB2::operationB()
}

特點

  • 優點:將產品族的創建封裝,保證產品間的兼容性;易于切換產品系列。
  • 缺點:新增產品族需修改抽象工廠及其所有子類,違反開閉原則;實現復雜。

四、三者對比總結

維度簡單工廠模式工廠方法模式抽象工廠模式
核心思想將對象創建邏輯封裝在一個工廠類中定義創建對象的接口,由子類實現具體創建邏輯提供創建一系列相關產品的接口,無需指定具體類
工廠數量一個工廠類一個抽象工廠和多個具體工廠一個抽象工廠和多個具體工廠
產品數量一個產品等級結構一個產品等級結構多個產品等級結構(產品族)
擴展性新增產品需修改工廠類,違反開閉原則新增產品只需添加新的具體工廠,符合開閉原則新增產品族需修改抽象工廠,違反開閉原則
適用場景產品種類少且創建邏輯簡單需要靈活擴展創建邏輯的場景創建相互依賴的產品族的場景
復雜度簡單中等復雜

五、選擇建議

  1. 優先使用簡單工廠:當產品種類少且創建邏輯固定時。
  2. 使用工廠方法:當需要擴展性,且產品屬于同一等級結構時。
  3. 使用抽象工廠:當需要創建多個相關產品,且產品間有依賴關系時。

在實際應用中,可根據需求靈活組合這些模式,例如在抽象工廠中使用工廠方法實現具體產品的創建,或使用簡單工廠管理產品注冊。


如果這篇文章對你有所幫助,渴望獲得你的一個點贊!

在這里插入圖片描述

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

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

相關文章

博圖SCL中CONTINUE語句詳解:高效循環控制案例

博圖SCL中CONTINUE語句詳解&#xff1a;高效循環控制利器 在博圖&#xff08;TIA Portal&#xff09;的SCL&#xff08;結構化控制語言&#xff09;編程中&#xff0c;CONTINUE語句是優化循環流程的強大工具。它允許您**跳過當前循環迭代的剩余代碼&#xff0c;直接進入下一次…

django HttpResponse 加返回碼

在Django框架中&#xff0c;HttpResponse對象是用來構造HTTP響應并將其發送回客戶端的。當你創建一個HttpResponse對象時&#xff0c;你可以指定一個返回碼&#xff08;或狀態碼&#xff09;&#xff0c;這是HTTP響應的一部分&#xff0c;用來表示請求的處理結果。狀態碼是三位…

【俄語圖片文字識別】批量識別俄語圖片文字,識別俄語圖片文字的操作步驟和注意事項

場景&#xff1a;在俄語學習&#xff0c;俄語工作中經常遇到一些文字圖片&#xff0c;如何將韓語圖片文字從圖片上扣下來&#xff0c;我們可以直接復制粘貼&#xff0c;提高我們的工作效率 我們會用到一款小工具&#xff1a; 軟件操作步驟&#xff1a; 第一步、打開軟件 第二…

關于AB PLC的ethernet/IP 通信 c++搭建

1.下載開源的libplctag庫 2.通過Cmake-gui生成工程文件 3.編譯生成對應的Debug 4.配置VS studio 源碼 #include "libplctag.h" #include <cstring> #include <iostream> #include <thread> int main() { plc_tag_set_debug_level(PLCTAG_DEB…

實驗分享|自研局部DIC-GPU算法與開源GPU算法對比實驗

1實驗背景 數字圖像相關法DIC是材料力學領域研究的關鍵技術&#xff0c;其中局部DIC憑借亞像素級精度、全場測量等優勢&#xff0c;成為材料局部變形分析的優選方案。傳統CPU計算難以應對局部DIC數萬個子區并行計算需求&#xff0c;新興GPU算法一定程度提高了計算效率&#xf…

P2066 機器分配

P2066 機器分配 - 洛谷 題目描述 總公司擁有高效設備M臺&#xff0c;準備分給下屬的N個分公司。各分公司若獲得這些設備&#xff0c;可以為國家提供一定的盈利。問&#xff1a;如何分配這M臺設備才能使國家得到的盈利最大&#xff1f;求出最大盈利值。其中M?15&#xff0c;N…

Vue 復制頁面內容

方法 1&#xff1a;使用 document.execCommand(copy) 在用戶觸發的事件中 這種方法適用于用戶觸發的事件&#xff08;如點擊按鈕&#xff09;&#xff0c;因為這是 execCommand(copy) 的唯一允許場景。 <template><button click"copyToClipboard">復制…

暑期前端訓練day1

js——記憶函數 2025-06-19 day1 一、記憶函數Ⅰ&#xff1a; 鏈接&#xff1a;https://leetcode.cn/problems/memoize/?envTypeproblem-list-v2&envIdGR5hbGen (1) 題意&#xff1a;給定一個函數&#xff0c;返回一個記憶版的函數&#xff0c;其中你只會包含三個可能輸…

鴻蒙網絡編程系列54-倉頡版實現Smtp郵件發送客戶端

1. SMTP郵件發送客戶端 在本系列的第4篇文章《鴻蒙網絡編程系列4-實現SMTP郵件發送客戶端》中&#xff0c;基于ArkTS語言在API9環境下使用TCPSocket對象演示了SMTP客戶端的實現&#xff0c;并且通過騰訊郵件服務器執行了實際的郵件發送。不過&#xff0c;在2024年末&#xff0…

【慧游魯博】【12】UI美化·圖標選擇與變換·動態交互·格式定義

文章目錄 圖標設計迭代過程初始版本問題分析優化措施 游覽畫卷美化原因當前效果展示美化步驟(1) 代碼修改結構優化CSS&#xff08;優化樣式&#xff09; (2) 圖標選擇&#xff08;4種方案&#xff09;(3) 交互優化 版本一版本二1. 修改HTML結構2. 新增CSS樣式色彩控制技術性能優…

IMU介紹

IMU(Inertial Measurement Unit,慣性測量單元)是一種基于慣性原理的傳感器,通過測量物體的加速度和角速度來獲取運動狀態信息。以下從技術原理、核心組件、應用場景及關鍵指標等方面展開詳細解析: 一、IMU的技術原理與核心組件 1. 工作原理 慣性力學基礎:利用牛頓第二定…

MOS管和比較器

目錄 前言一、前置器件復習使用1.比較器工作特性2.光電二極管3.紅外出水水龍頭4.溫控風扇工作原理 二、MOS管1.前置1.1 增強型MOS管1.2 耗盡型MOS管1.3 四種1.4 比較 2.基本結構3.導通條件4.開關電路的設計方法5.寄生電容問題6.寄生二極管不能忽略7.Nmos管做電源開關的注意事項…

從代碼學習深度強化學習 - Double DQN PyTorch版

文章目錄 前言理論篇:為什么需要 Double DQN?代碼實現篇:構建一個 Double DQN 智能體2.1 項目設置與輔助函數2.2 環境 (Environment)2.3 DQN 的核心組件2.3.1 Replay Buffer (經驗回放池)2.3.2 Q-Network (Q網絡)2.3.3 The Double DQN Agent (Double DQN 智能體)訓練與結果3…

四非鼠鼠計算機專業的保研分享

四非鼠鼠的計算機專業保研分享 1.前言 鼠鼠的本科學校是一所不怎么出名的四非院校&#xff0c;專業是計算機科學與技術。在寫下這篇文章時&#xff0c;鼠鼠并不是為了炫耀什么&#xff0c;而是想把自己在保研路上的一些踩坑經歷分享出來&#xff0c;尤其是寫給那些和我一樣&a…

【C++詳解】STL-vector使用底層剖析和實現

文章目錄 vector介紹vector和string的區別補充知識initializer_listemplace_back結構化綁定 vector的使用構造析構遍歷修改insertfind流插入/流提取vector\<vector>(楊輝三角) vector模擬實現淺品STL源碼構造函數拷貝構造多參數構造迭代器區間構造n個val初始化swapoperat…

MySql升級安裝、socket 及密碼重置

升級 項目需要使用Mysql8.0, 查看自己的ubuntu22.04上mysql版本為5.7&#xff0c; 使用以下命令自動升級到8.0版本。 sudo apt install Mysqlsock錯誤&#xff1a; Can’t connect to local MySQL server through socket 運行mysql -u -p 報以下錯誤&#xff1a; ERROR 200…

Python網絡爬蟲技術:從入門到實戰

在當今數字化時代&#xff0c;網絡爬蟲技術已經成為數據挖掘和信息收集的重要工具。通過網絡爬蟲&#xff0c;我們可以高效地從互聯網上獲取大量有價值的數據&#xff0c;用于數據分析、市場研究、學術研究等多種場景。本文將帶你從零開始&#xff0c;了解Python網絡爬蟲的基本…

偏微分方程初值問題求解

題目 問題 2. (a) u t + 3 u x ? 2 u y = x ; u t + x u x + y u y = x ; u_t + 3u_x - 2u_y = x; \quad u_t + xu_x + yu_y = x; ut?+3ux??2uy?=x;ut?+xux?+yuy?=x; u t + x u x ? y u y = x ; u t + y u x + x u y = x ; u_t + xu_x - yu_y = x; \quad u_t + yu_…

【專業梳理】PMP知識體系,以SIPOC流程圖為核心的質量工具擴展

??1. SIPOC流程圖:質量管理的起點?? SIPOC(Supplier-Input-Process-Output-Customer)是六西格瑪和流程管理中的核心工具,用于定義和優化跨職能流程。在PMBOK中,它與質量管理知識領域(尤其是質量規劃、質量保證)緊密關聯: ??質量規劃??:通過SIPOC明確流程邊界…

OpenCV指定pid和vid通過MSMF打開攝像頭

在基于OpenCV的項目中&#xff0c;實際開發過程會面臨設備上存在多個攝像頭&#xff0c;需要指定攝像頭的pid和vid打開攝像頭。在OpenCV通過MSMF打開攝像頭時&#xff0c;需要傳入攝像頭的index&#xff0c;因此需要在打開該攝像頭前需要找出攝像頭的index&#xff0c;下面給出…