Linux C++ 045-設計模式之工廠模式

Linux C++ 045-設計模式之工廠模式

本節關鍵字:Linux、C++、設計模式、簡單工廠模式、工廠方法模式、抽象工廠模式
相關庫函數:

簡單工廠模式

基本簡介

從設計模式的類型上來說,簡單工廠模式是屬于創建型模式,又叫做靜態工廠方法(Static Factory Method)模式,但不屬于23種GOF設計模式之一。

簡單工廠模式是由一個工廠對象決定創建出哪一種產品類的實例。簡單工廠模式是工廠模式家族中最簡單實用的模式,可以理解為是不同工廠模式的一個特殊實現。

實現方式

簡單工廠模式的實質是由一個工廠類根據傳入的參數,動態決定應該創建哪一個產品類(這些產品類繼承自一個父類或接口)的實例。

角色結構

工廠角色:簡單工廠模式的核心,它負責實現創建所有實例的內部邏輯。工廠類可以被外界直接調用,創建所需的產品對象。

抽象產品角色:簡單工廠模式所創建的所有對象的父類,它負責描述所有實例所共有的公共接口。

具體產品角色:是簡單工廠模式的創建目標,所有創建的對象都是充當這個角色的某個具體類的實例。

class SimpleOperation
{
public:SimpleOperation() {numberA = 1;numberB = 1;}
public:double numberA, numberB;virtual double getResult() = 0;
};class AddSimpleOperation : public SimpleOperation
{double getResult() {return numberA + numberB;}
};
class SubSimpleOperation : public SimpleOperation
{double getResult() {return numberA - numberB;}
};
class MulSimpleOperation : public SimpleOperation
{double getResult() {return numberA * numberB;}
};
class DivSimpleOperation : public SimpleOperation
{double getResult() {return numberA / numberB;}
};
class OperSimpleOperation
{
public:static SimpleOperation* createOperation(char c){switch (c){case '+':return new AddSimpleOperation;break;case '-':return new SubSimpleOperation;break;case '*':return new MulSimpleOperation;break;case '/':return new DivSimpleOperation;break;}}
};
int main_SimpleFactory()
{OperationSimple* oper = operFactorySimple::createOperation('+');oper->numberA = 123;oper->numberB = 456;cout << oper->getResult() << endl;return 0;
}

工廠方法模式

基本簡介

工廠方法(FactoryMethod)模式是類的創建模式,其用意是定義一個創建產品對象的工廠接口,將實際創建工作推遲到子類中。

工廠方法模式的實質是“定義一個創建對象的接口,但讓實現這個接口的類來決定實例化哪個類。工廠方法讓類的實例化推遲到子類中進行。”

在工廠方法模式中,核心的工廠類不再負責所有產品的創建,而是將具體創建工作交給子類去做。這個核心類僅僅負責給出具體工廠必須實現的接口,而不接觸哪一個產品類被實例化這種細節。這使得工廠方法模式可以允許系統在不修改工廠角色的情況下引進新產品。

在Factory Method模式中,工廠類與產品類往往具有平行的等級結構,它們之間一一對應。

實現方式

工廠方法模式的實質是:定義一個創建對象的接口,但讓實現這個接口的類來決定實例化哪個類。工廠方法讓類的實例化推遲到子類中進行。

角色結構

抽象工廠(Creator)角色:是工廠方法模式的核心,與應用程序無關。任何在模式中創建的對象的工廠類必須實現這個接口。

具體工廠(Concrete Creator)角色:這是實現抽象工廠接口的具體工廠類,包含與應用程序密切相關的邏輯,并且受到應用程序調用以創建產品對象。

抽象產品(Product)角色:工廠方法模式所創建的對象的超類型,也就是產品對象的共同父類或共同擁有的接口。

具體產品(Concrete Product)角色:這個角色實現了抽象產品角色所定義的接口。某具體產品有專門的具體工廠創建,它們之間往往一一對應。

class OperationMethod
{
public:OperationMethod() {}~OperationMethod() {}
public:double numberA, numberB;virtual double getResult() = 0;
};
class AddOperationMethod : public OperationMethod
{double getResult() {return numberA + numberB;}
};
class SubOperationMethod : public OperationMethod
{double getResult() {return numberA - numberB;}
};
class MulOperationMethod : public OperationMethod
{double getResult() {return numberA * numberB;}
};
class DivOperationMethod : public OperationMethod
{double getResult() {return numberA / numberB;}
};
class IFactoryMethod
{
public:virtual OperationMethod* createOperation() = 0;
};
class AddFactoryMethod : public IFactoryMethod
{
public:static OperationMethod* createOperation() {return new AddOperationMethod();}
};
class SubFactoryMethod : public IFactoryMethod
{
public:static OperationMethod* createOperation() {return new SubOperationMethod();}
};
class MulFactoryMethod : public IFactoryMethod
{
public:static OperationMethod* createOperation() {return new MulOperationMethod();}
};
class DivFactoryMethod : public IFactoryMethod
{
public:static OperationMethod* createOperation() {return new DivOperationMethod();}
};
int main_MethodFactory()
{OperationMethod* oper = MulFactoryMethod::createOperation();oper->numberA = 666;oper->numberB = 999;cout << oper->getResult() << endl;return 0;
}

抽象工廠模式

基本簡介

抽象工廠模式是所有形態的工廠模式中最為抽象和最具一般性的一種形態。抽象工廠模式是指當有多個抽象角色時,使用的一種工廠模式。抽象工廠模式可以向客戶端提供一個接口,使客戶端在不必指定產品的具體的情況下,創建多個產品族中的產品對象。根據里氏替換原則,任何接受父類型的地方,都應當能夠接受子類型。因此,實際上系統所需要的,僅僅是類型與這些抽象產品角色相同的一些實例,而不是這些抽象產品的實例。換言之,也就是這些抽象產品的具體子類的實例。工廠類負責創建抽象產品的具體子類的實例。

當每個抽象產品都有多于一個的具體子類的時候,工廠角色怎么知道實例化哪一個子類呢?比如每個抽象產品角色都有兩個具體產品。抽象工廠模式提供兩個具體工廠角色,分別對應于這兩個具體產品角色,每一個具體工廠角色只負責某一個產品角色的實例化。每一個具體工廠類只負責創建抽象產品的某一個具體子類的實例。

每一個模式都是針對一定問題的解決方案,工廠方法模式針對的是一個產品等級結構;而抽象工廠模式針對的是多個產品等級結構。

實現方式

根據里氏替換原則,任何接受父類型的地方,都應當能夠接受子類型。因此,實際上系統所需要的,僅僅是類型與這些抽象產品角色相同的一些實例,而不是這些抽象產品的實例。換言之,也就是這些抽象產品的具體子類的實例。工廠類負責創建抽象產品的具體子類的實例。

產品族

產品族是指位于不同產品等級結構中,功能相關聯的產品組成的家族。一般是位于不同的等級結構中的相同位置上。顯然,每一個產品族中含有產品的數目,與產品等級結構的數目是相等的,形成一個二維的坐標系,水平坐標是產品等級結構,縱坐標是產品族。叫做相圖。

當有多個不同的等級結構的產品時,如果使用工廠方法模式就勢必要使用多個獨立的工廠等級結構來對付這些產品的等級結構。如果這些產品等級結構是平行的,會導致多個平行的工廠等級結構。

抽象工廠模式使用同一個 工廠等級結構負責這些不同產品等級結構產品對象的創建。

對于每一個產品族,都有一個具體工廠。而每一個具體工廠創建屬于同一個產品族,但是分屬于不同等級結構的產品。

通過引進抽象工廠模式,可以處理具有相同(或者相似)等級結構的多個產品族中的產品對象的創建問題。

由于每個具體工廠角色都需要負責兩個不同等級結構的產品對象的創建,因此每個工廠角色都需要提供兩個工廠方法,分別用于創建兩個等級結構的產品。既然每個具體工廠角色都需要實現這兩個工廠方法,所以具有一般性,不妨抽象出來,移動到抽象工廠角色中加以聲明。

class IUser
{
public:virtual void getUser() = 0;virtual void setUser() = 0;
};
class SqlUser : public IUser
{
public:void getUser() {cout << "在sql中返回user" << endl;}void setUser() {cout << "在sql中設置user" << endl;}
};
class AccessUser : public IUser
{
public:void getUser() {cout << "在Access中返回user" << endl;}void setUser() {cout << "在Access中設置user" << endl;}
};
class IDepartment
{
public:virtual void getDepartment() = 0;virtual void setDepartment() = 0;
};
class SqlDepartment : public IDepartment
{
public:void getDepartment() {cout << "在sql中返回Department" << endl;}void setDepartment() {cout << "在sql中設置Department" << endl;}
};
class AccessDepartment : public IDepartment
{
public:void getDepartment() {cout << "在Access中返回Department" << endl;}void setDepartment() {cout << "在Access中設置Department" << endl;}
};
class IFactory
{
public:virtual IUser* createUser() = 0;virtual IDepartment* createDepartment() = 0;
};
class SqlFactory : public IFactory
{
public:IUser* createUser() {return new SqlUser();}IDepartment* createDepartment() {return new SqlDepartment();}
};
class AccessFactory :public IFactory
{
public:IUser* createUser() {return new AccessUser();}IDepartment* createDepartment() {return new AccessDepartment();}
};
class DataAccess // 簡單工廠類
{
private:static string db;
public:static IUser* createUser() {if (db == "access") {return new AccessUser();}else if (db == "sql") {return new SqlUser();}}static IDepartment* createDeparment() {if (db == "access") {return new AccessDepartment();}else if (db == "sql") {return new SqlDepartment();}}
};
string DataAccess::db = "sql";int main_AbstractFactory()
{// IFactory* factory = new SqlFactory();IFactory* factory;IUser* user;IDepartment* department;factory = new AccessFactory();user = factory->createUser();department = factory->createDepartment();user->getUser();user->setUser();department->getDepartment();department->setDepartment();// 簡單工廠類的調用user = DataAccess::createUser();department = DataAccess::createDeparment();user->getUser();user->setUser();department->getDepartment();department->setDepartment();return 0;
}

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

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

相關文章

10、Python之寫出更加Pythonic的代碼:unpacking拆包機制

引言 有些小伙伴有其他編程語言的學習、使用的經驗&#xff0c;然后遷移到Python。一般會比完全的新手小白&#xff0c;更快速地把Python用起來。這是他們的優勢&#xff0c;但也是他們的劣勢。 之所以這么說&#xff0c;是因為從其他編程語言帶過來的&#xff0c;除了相通的編…

MOJO語言中的字典和哈希表:數據結構的靈活性與效率

MOJO是一種編程語言&#xff0c;它以其獨特的語法和對現代編程范式的支持而聞名。在MOJO中&#xff0c;字典&#xff08;也稱為哈希表或散列表&#xff09;是一種非常重要的數據結構&#xff0c;它允許開發者以鍵值對的形式存儲和檢索數據。本文將深入探討MOJO語言中的字典和哈…

第十八節 LLaVA如何按需構建LORA訓練(視覺、語言、映射多個組合訓練)

文章目錄 前言一、基于llava源碼構建新的參數1、添加lora_vit參數2、訓練命令腳本設置二、修改源碼,構建lora訓練1、修改源碼-lora訓練2、LLM模型lora加載3、VIT模型加載4、權重凍結操作5、結果顯示三、實驗結果前言 如果看了我前面文章,想必你基本對整個代碼有了更深認識。…

Raylib 實現超大地圖放大縮小與兩種模式瓦片地圖刷新

原理&#xff1a; 一種刷新模式&#xff1a; 在宮格內整體刷新&#xff0c;類似九宮格移動到邊緣&#xff0c;則九宮格整體平移一個宮格&#xff0c;不過這里是移動一個瓦片像素&#xff0c;實際上就是全屏刷新&#xff0c;這個上限是 筆記本 3060 70幀 100*100個瓦片每幀都…

數據庫之MQL

1&#xff0c;查詢所有 mysql> select * from grade;2&#xff0c; mysql> select id,firstname,lastname from grade;3&#xff0c; mysql> select firstname,lastname from grade where id > 4;4&#xff0c; mysql> select * from grade where sex f;5&…

C++中的函數指針

C中的函數指針 在C中&#xff0c;函數指針是一個指向函數的指針&#xff0c;可以用來調用函數。函數指針的聲明方式如下&#xff1a; 返回類型 (*指針變量名)(參數列表);例如&#xff0c;如果有一個函數&#xff1a; int add(int a, int b) {return a b; }可以聲明一個指向…

微服務通信新紀元:Eureka與分布式服務網格的融合

微服務通信新紀元&#xff1a;Eureka與分布式服務網格的融合 引言 在微服務架構中&#xff0c;服務間的通信是構建分布式系統的核心。Eureka作為Netflix開源的服務發現框架&#xff0c;提供了服務注冊與發現的功能&#xff0c;而服務網格技術則為服務間通信提供了更細粒度的控…

Hive/Spark窗口函數

窗口函數 hive文檔鏈接 spark文檔鏈接 1. OVER支持的函數 自然序編號 Syntax: ROW_NUMBER按等級編號 Syntax: RANK | DENSE_RANK | PERCENT_RANK分組內分桶&#xff0c;并返回對應桶的序號 Syntax: NTILE(n)Analytic Functions&#xff08;分析函數&#xff09; Syntax: CUM…

odoo17 常見升級問題

通用問題 模型名變更 字段變更 方法名變更 方法參數變更 xml數據結構定義變化 xml的id變更 view視圖變化&#xff0c;導致xpath路徑出差 template結構變化&#xff0c;&#xff0c;導致xpath路徑出差&#xff0c;或者id不存在 升16問題 前端owl的架構變化 升17問題 前端 標…

什么,有狗快跑!慢著,這次手把手教你怎么過安全狗!(sql注入篇)

前言 在記憶里上次繞安全狗還是在上次&#xff0c;開開心心把自己之前繞過狗的payload拿出來&#xff0c;發現全部被攔截了&#xff0c;事情一下子就嚴肅起來了&#xff0c;這就開整。 環境 本次環境如下sqli-lab的sql注入靶場 網站安全狗APACHE版V4.0版本的最高防護等級繞過…

秋招Java后端開發沖刺——并發篇2(ThreadLocal、Future接口)

本文對ThreadLocal類和Future接口進行了總結概括&#xff0c;包括ThreadLocal類的原理、內存泄露等問題&#xff0c;和Future接口的使用等問題。 一、ThreadLocal 1. 介紹 ThreadLocal&#xff08;線程局部變量&#xff09;是Java中的一個類&#xff0c;線程通過維護一個本地…

一文帶你徹底搞懂什么是責任鏈模式!!

文章目錄 什么是責任鏈模式&#xff1f;詳細示例SpingMVC 中的責任鏈模式使用總結 什么是責任鏈模式&#xff1f; 在我們日常生活中&#xff0c;經常會出現一種場景&#xff1a;一個請求需要經過多個對象的處理才能得到最終的結果。比如&#xff0c;一個請假申請&#xff0c;需…

STM32智能倉庫管理系統教程

目錄 引言環境準備智能倉庫管理系統基礎代碼實現&#xff1a;實現智能倉庫管理系統 4.1 數據采集模塊 4.2 數據處理與控制算法 4.3 通信與網絡系統實現 4.4 用戶界面與數據可視化應用場景&#xff1a;倉庫管理與優化問題解決方案與優化收尾與總結 1. 引言 智能倉庫管理系統通…

藏漢翻譯通作為翻譯軟件的優勢有哪些?

藏漢翻譯通作為一款專業的藏漢雙語翻譯軟件&#xff0c;具有以下優勢&#xff1a; 人工智能技術應用&#xff1a;藏漢翻譯通利用了人工智能翻譯和語音識別合成技術&#xff0c;提供智能藏文翻譯服務。 高準確率&#xff1a;文字識別準確率可達90%&#xff0c;語音識別轉化文字…

蒼穹外賣--導入分類模塊功能代碼

把各層代碼拷貝到所需文件夾下&#xff0c; 進行編譯 在運行 提交和推送倉庫

解鎖AI大模型潛能:預訓練、遷移學習與中間件編程的協同藝術

在人工智能的浩瀚星空中&#xff0c;大型預訓練模型&#xff08;Large Language Models, LLMs&#xff09;猶如璀璨的星辰&#xff0c;引領著技術革新的浪潮。這些模型通過海量數據的滋養&#xff0c;學會了理解語言、生成文本乃至執行復雜任務的能力。然而&#xff0c;要讓這些…

【正點原子i.MX93開發板試用連載體驗】項目計劃和開箱體驗

本文最早發表于電子發燒友&#xff1a;【   】【正點原子i.MX93開發板試用連載體驗】基于深度學習的語音本地控制 - 正點原子學習小組 - 電子技術論壇 - 廣受歡迎的專業電子論壇! (elecfans.com)https://bbs.elecfans.com/jishu_2438354_1_1.html 有一段時間沒有參加電子發…

Pyspider WebUI 未授權訪問致遠程代碼執行漏洞復現

0x01 產品簡介 Pyspider是由國人binux編寫的強大的網絡爬蟲系統,它帶有強大的WebUI(Web用戶界面),為用戶提供了可視化的編寫、調試和管理爬蟲的能力。這一特點使得Pyspider在爬蟲框架中脫穎而出,尤其適合那些希望快速上手并高效開發爬蟲的用戶。允許用戶直接在網頁上編寫…

for in和for of對比

不同點&#xff1a; 時間點不同&#xff1a;for in 在js出現之初就有&#xff0c;for of出現在ES6之后 遍歷的內容不同&#xff1a;for in用于遍歷對象的可枚舉屬性(包括原型鏈上的可枚舉屬性)&#xff0c;for of用于遍歷可迭代對象的值 看個例子 // for in const arr [a,b,…

Linux--線程的控制

目錄 0.前言 1.pthread庫 2.關于控制線程的接口 2.1.創建線程&#xff08;pthread_create&#xff09; 2.2.線程等待&#xff08;pthread_join&#xff09; 代碼示例1&#xff1a; ?編輯 ***一些問題*** 2. 3.創建多線程 3.線程的終止 &#xff08;pthread_exit /…