C++設(shè)計(jì)模式編程中簡單工廠與工廠方法模式的實(shí)例對比
簡單工廠模式實(shí)例
題目:實(shí)現(xiàn)計(jì)算器的輸入2個(gè)數(shù)和運(yùn)算符,得到結(jié)果
工程結(jié)構(gòu):
(1)頭文件
COperationFactory.h(運(yùn)算符工廠類)
(2)源文件
SimpleFactory.cpp(客戶端應(yīng)用類,主函數(shù)所在)
(3)運(yùn)算類
COperation.cpp(運(yùn)算符基類)
COperation.h
COperationAdd.h(加法運(yùn)算符子類,繼承于COperation)
COperationDiv.h (除法運(yùn)算符子類,繼承于COperation)
COperationMul.h (乘法運(yùn)算符子類,繼承于COperation)
COperationSub.h(減法運(yùn)算符子類,繼承于COperation)
============= 代碼實(shí)現(xiàn)部分 =============
COperationFactory.h(運(yùn)算符工廠類)
/************************************************************************/
/* 運(yùn)算符工廠類 */
/************************************************************************/
#ifndef _OPERATION_FACTORY_H_
#define _OPERATION_FACTORY_H_
#include "stdafx.h"
#include "COperation.h"
#include "COperationAdd.h"
#include "COperationSub.h"
#include "COperationMul.h"
#include "COperationDiv.h"
#include "COperationFactory.h"
class COperationFactory
{
public:
COperationFactory(){};
~COperationFactory(){};
// 根據(jù)入?yún)⒌牟煌?,?chuàng)建其對應(yīng)的運(yùn)算符類指針。就像是個(gè)工廠,創(chuàng)建用戶指定的運(yùn)算符類指針
static COperation* NewOperation(const string& strOperate)
{
// 入?yún)⒑戏ㄐ耘袛?,防止后面的strOperate[0]發(fā)生越界訪問
if (strOperate.size() != 1)
{
return NULL;
}
COperation* pOperation = NULL;
switch (strOperate[0])
{
case '+':
pOperation = new COperationAdd();
break;
case '-':
pOperation = new COperationSub();
break;
case '*':
pOperation = new COperationMul();
break;
case '/':
pOperation = new COperationDiv();
break;
default:
break;
}
return pOperation;
};
};
#endif _OPERATION_FACTORY_H_
COperation.cpp(運(yùn)算符基類)
#include "stdafx.h"
#include "COperation.h"
COperation::COperation()
: _dNumA(0)
, _dNumB(0)
{
}
COperation.h
/************************************************************************/
/* 運(yùn)算符基類 */
/************************************************************************/
#ifndef _COPERATION_H_
#define _COPERATION_H_
class COperation
{
public:
COperation();
~COperation(){};
// 設(shè)置被運(yùn)算數(shù)
void SetNumA(double dNumA)
{
_dNumA = dNumA;
};
// 獲取被運(yùn)算數(shù)
double GetNumA()
{
return _dNumA;
};
// 設(shè)置運(yùn)算數(shù)
void SetNumB(double dNumB)
{
_dNumB = dNumB;
};
// 獲取運(yùn)算數(shù)
double GetNumB()
{
return _dNumB;
};
// 計(jì)算結(jié)果且在子類中實(shí)現(xiàn)各自的運(yùn)算方法結(jié)果
virtual double Result()
{
double dResult = 0;
return dResult;
}
private:
double _dNumA;
double _dNumB;
};
#endif _COPERATION_H_
COperationAdd.h(加法運(yùn)算符子類,繼承于COperation)
/************************************************************************/
/* 加法運(yùn)算符子類,繼承于運(yùn)算符基類 */
/************************************************************************/
#ifndef _COPERATION_ADD_H_
#define _COPERATION_ADD_H_
#include "COperation.h"
class COperationAdd : public COperation
{
public:
COperationAdd(){};
~COperationAdd(){};
double Result()
{
return (GetNumA() + GetNumB());
};
};
#endif _COPERATION_ADD_H_
COperationDiv.h (除法運(yùn)算符子類,繼承于COperation)
/************************************************************************/
/* 除法運(yùn)算符子類,繼承于運(yùn)算符基類 */
/************************************************************************/
#ifndef _COPERATION_DIV_H_
#define _COPERATION_DIV_H_
#include "COperation.h"
class COperationDiv : public COperation
{
public:
COperationDiv(){};
~COperationDiv(){};
double Result()
{
double dResult = 0;
if (0 != GetNumB())
{
dResult = (GetNumA() / GetNumB());
}
else
{
cout << "error: divisor is ";
}
return dResult;
};
};
#endif _COPERATION_DIV_H_
COperationMul.h (乘法運(yùn)算符子類,繼承于COperation)
/************************************************************************/
/* 乘法運(yùn)算符子類,繼承于運(yùn)算符基類 */
/************************************************************************/
#ifndef _COPERATION_MUL_H_
#define _COPERATION_MUL_H_
#include "COperation.h"
class COperationMul : public COperation
{
public:
COperationMul(){};
~COperationMul(){};
double Result()
{
return (GetNumA() * GetNumB());
};
};
#endif _COPERATION_MUL_H_
COperationSub.h(減法運(yùn)算符子類,繼承于COperation)
/************************************************************************/
/* 減法運(yùn)算符子類,繼承于運(yùn)算符基類 */
/************************************************************************/
#ifndef _COPERATION_SUB_H_
#define _COPERATION_SUB_H_
#include "COperation.h"
class COperationSub : public COperation
{
public:
COperationSub(){};
~COperationSub(){};
double Result()
{
return (GetNumA() - GetNumB());
};
};
#endif _COPERATION_SUB_H_
SimpleFactory.cpp(客戶端應(yīng)用類,主函數(shù)所在)
// SimpleFactory.cpp : 定義控制臺應(yīng)用程序的入口點(diǎn)。
//
#include "stdafx.h"
#include "COperationFactory.h"
int _tmain(int argc, _TCHAR* argv[])
{
// 通過運(yùn)算符工廠創(chuàng)建加法運(yùn)算
COperation* OperAdd = COperationFactory::NewOperation("+");
if (NULL != OperAdd)
{
OperAdd->SetNumA(168); // 設(shè)置被加數(shù)
OperAdd->SetNumB(105); // 設(shè)置加數(shù)
cout << "168 + 105 = " << (OperAdd->Result()) << endl;
}
// 通過運(yùn)算符工廠創(chuàng)建減法運(yùn)算
COperation* OperSub = COperationFactory::NewOperation("-");
if (NULL != OperSub)
{
OperSub->SetNumA(168); // 設(shè)置被減數(shù)
OperSub->SetNumB(105); // 設(shè)置減數(shù)
cout << "168 - 105 = " << (OperSub->Result()) << endl;
}
// 通過運(yùn)算符工廠創(chuàng)建乘法運(yùn)算
COperation* OperMul = COperationFactory::NewOperation("*");
if (NULL != OperMul)
{
OperMul->SetNumA(168); // 設(shè)置被乘數(shù)
OperMul->SetNumB(105); // 設(shè)置乘數(shù)
cout << "168 * 105 = " << (OperMul->Result()) << endl;
}
// 通過運(yùn)算符工廠創(chuàng)建除法運(yùn)算
COperation* OperDiv = COperationFactory::NewOperation("/");
if (NULL != OperDiv)
{
OperDiv->SetNumA(168); // 設(shè)置被除數(shù)
OperDiv->SetNumB(105); // 設(shè)置除數(shù)
cout << "168 / 105 = " << (OperDiv->Result()) << endl;
OperDiv->SetNumB(0); // 改變除數(shù)
cout << (OperDiv->Result()) << endl;
}
// 阻止控制臺進(jìn)程結(jié)束,便于查看結(jié)果
int nEnd = 0;
cin >> nEnd;
return 0;
}
抽象工廠模式實(shí)例
工程結(jié)構(gòu):
(1)抽象產(chǎn)品類
IFruit.h
(2)抽象工廠類
IFruitGardener.h
(3)具體產(chǎn)品類
CApple.h
CGrape.h
CStrawberry.h
(4)具體工廠類
CAppleGardener.h
CGrapeGardener.h
CStrawberryGardener.h
(5)客戶端
FactoryMethodApplication.cpp
(1)抽象產(chǎn)品類
IFruit.h
/************************************************************************/
/* 抽象水果類(abstract Product) */
/************************************************************************/
#ifndef _IFRUIT_H_
#define _IFRUIT_H_
#include <string>
#include <iostream>
using namespace std;
class IFruit
{
public:
virtual void grow() = 0;
virtual void harvest() = 0;
virtual void plant() = 0;
};
#endif _IFRUIT_H_
(2)抽象工廠類
IFruitGardener.h
/************************************************************************/
/* 抽象水果園丁類(abstract Factory) */
/************************************************************************/
#ifndef _IFRUIT_GARDENER_H_
#define _IFRUIT_GARDENER_H_
#include "IFruit.h"
class IFruitGardener
{
public:
virtual IFruit* Factory() = 0;
};
#endif _IFRUIT_GARDENER_H_
(3)具體產(chǎn)品類
CApple.h
/************************************************************************/
/* 具體的蘋果類(Concrete Product) */
/************************************************************************/
#ifndef _APPLE_H_
#define _APPLE_H_
#include "IFruit.h"
class CApple : public IFruit
{
public:
void grow()
{
cout << "Apple is growing..." << endl;
};
void harvest()
{
cout << "Apple has been harvested." << endl;
};
void plant()
{
cout << "Apple has been planted." << endl;
};
int GetTreeAge()
{
return m_iAppleTreeAge;
};
void SetTreeAge(const int iAge)
{
m_iAppleTreeAge = iAge;
}
private:
int m_iAppleTreeAge;
};
#endif _APPLE_H_
CGrape.h
/************************************************************************/
/* 具體的葡萄類(Concrete Product) */
/************************************************************************/
#ifndef _GRAPE_H_
#define _GRAPE_H_
#include "IFruit.h"
class CGrape : public IFruit
{
public:
void grow()
{
cout << "Grape is growing..." << endl;
};
void harvest()
{
cout << "Grape has been harvested." << endl;
};
void plant()
{
cout << "Grape has been planted." << endl;
};
bool GetSeedless()
{
return m_bSeedless;
};
void SetSeedless(const bool bSeedless)
{
m_bSeedless = bSeedless;
};
private:
bool m_bSeedless;
};
#endif _GRAPE_H_
CStrawberry.h
/************************************************************************/
/* 具體的草莓類(Concrete Product) */
/************************************************************************/
#ifndef _STRAWBERRY_H_
#define _STRAWBERRY_H_
#include "IFruit.h"
class CStrawberry : public IFruit
{
public:
void grow()
{
cout << "Strawberry is growing..." << endl;
};
void harvest()
{
cout << "Strawberry has been harvested." << endl;
};
void plant()
{
cout << "Strawberry has been planted." << endl;
};
};
#endif _STRAWBERRY_H_
(4)具體工廠類
CAppleGardener.h
/************************************************************************/
/* 具體的蘋果園丁類(Concrete Factory) */
/************************************************************************/
#ifndef _APPLE_GARDENER_H_
#define _APPLE_GARDENER_H_
#include "IFruitGardener.h"
#include "CApple.h"
class CAppleGardener : public IFruitGardener
{
public:
CAppleGardener():m_pApple(NULL){};
IFruit* Factory()
{
if (NULL == m_pApple)
{
m_pApple = new CApple();
}
return m_pApple;
};
private:
CApple* m_pApple;
};
#endif _APPLE_GARDENER_H_
CGrapeGardener.h
/************************************************************************/
/* 具體的葡萄園丁類(Concrete Factory) */
/************************************************************************/
#ifndef _GRAPE_GARDENER_H_
#define _GRAPE_GARDENER_H_
#include "IFruitGardener.h"
#include "CGrape.h"
class CGrapeGardener : public IFruitGardener
{
public:
CGrapeGardener():m_pGrape(NULL){};
IFruit* Factory()
{
if (NULL == m_pGrape)
{
m_pGrape = new CGrape();
}
return m_pGrape;
};
private:
CGrape* m_pGrape;
};
#endif _GRAPE_GARDENER_H_
CStrawberryGardener.h
/************************************************************************/
/* 具體的草莓園丁類(Concrete Factory) */
/************************************************************************/
#ifndef _STRAWBERRY_GARDENER_H_
#define _STRAWBERRY_GARDENER_H_
#include "IFruitGardener.h"
#include "CStrawberry.h"
class CStrawberryGardener : public IFruitGardener
{
public:
CStrawberryGardener():m_pStrawberry(NULL){};
IFruit* Factory()
{
if (NULL == m_pStrawberry)
{
m_pStrawberry = new CStrawberry();
}
return m_pStrawberry;
};
private:
CStrawberry* m_pStrawberry;
};
#endif _STRAWBERRY_GARDENER_H_
(5)客戶端
FactoryMethodApplication.cpp
// FactoryMethodApplication.cpp : 定義控制臺應(yīng)用程序的入口點(diǎn)。
//
#include "stdafx.h"
#include <Windows.h>
#include "IFruitGardener.h"
#include "CAppleGardener.h"
#include "CGrapeGardener.h"
#include "CStrawberryGardener.h"
int _tmain(int argc, _TCHAR* argv[])
{
static IFruitGardener* pFruitFactory1 = NULL;
static IFruitGardener* pFruitFactory2 = NULL;
static IFruit* pFruit1 = NULL;
static IFruit* pFruit2 = NULL;
pFruitFactory1 = new CAppleGardener();
if (NULL != pFruitFactory1)
{
pFruit1 = pFruitFactory1->Factory();
if (NULL != pFruit1)
{
pFruit1->grow();
pFruit1->harvest();
pFruit1->plant();
}
}
pFruitFactory2 = new CGrapeGardener();
if (NULL != pFruitFactory2)
{
pFruit2 = pFruitFactory2->Factory();
if (NULL != pFruit2)
{
pFruit2->grow();
pFruit2->harvest();
pFruit2->plant();
}
}
Sleep(10000);
return 0;
}
總結(jié)
首先無論是簡單工廠模式還是工廠方法模式都是把不變的地方提取出來,把容易發(fā)生變化的封裝起來。以達(dá)到做大程度的復(fù)用,和適應(yīng)用戶的變動(dòng),以及項(xiàng)目的擴(kuò)展。
一、簡單工廠模式
1.理解
又稱為靜態(tài)工廠模式,它專門定義一個(gè)類來負(fù)責(zé)創(chuàng)建其他類的實(shí)例,被創(chuàng)建的實(shí)例通常都具有相通的父類。由工廠類根據(jù)傳入的參數(shù)動(dòng)態(tài)決定應(yīng)該創(chuàng)建哪一個(gè)產(chǎn)品類的實(shí)例。它包含必要的判斷邏輯,能根據(jù)外界給定的信息,決定應(yīng)該穿件那個(gè)具體類的對象。簡單工廠模式可以理解為父親給兒子留了一筆錢,規(guī)定這筆錢可以用于上學(xué)、買房或者買車,然后讓兒子自己選擇用于哪一個(gè)。
2.優(yōu)點(diǎn)
工廠類包含必要的邏輯判斷,可以決定在什么時(shí)候創(chuàng)建哪一個(gè)類的實(shí)例,客戶端可以避免直接創(chuàng)建對象。這樣就可以實(shí)現(xiàn)對責(zé)任的分割,降低耦合性,明確了具體的職責(zé)和權(quán)力,有利于整個(gè)系統(tǒng)的優(yōu)化。
3.缺點(diǎn)
當(dāng)產(chǎn)品具有比較復(fù)雜的多層結(jié)構(gòu)時(shí),它的工廠類只有一個(gè),這時(shí)候再以不變應(yīng)萬變就成為它最大的缺點(diǎn)了。因?yàn)楣S類是整個(gè)組織的核心,它聚集了所有產(chǎn)品的創(chuàng)建邏輯,一旦工廠不能正常工作,整個(gè)系統(tǒng)都會受到影響,可擴(kuò)展性較差。擴(kuò)展性差一旦有新的需求,就不得不修改工廠邏輯,這樣就會導(dǎo)致工廠邏輯過為復(fù)雜,違背了開——閉原則。同時(shí)靜態(tài)工廠方法不利于形成基于繼承的等級結(jié)構(gòu)。
二、工廠方法模式
1.理解
它是一個(gè)粒度很小的設(shè)計(jì)模式,因?yàn)槟J降谋憩F(xiàn)只是一個(gè)抽象的方法。工廠方法模式定義了一個(gè)用于創(chuàng)建對象的界面,讓子類決定具體實(shí)例化哪一個(gè)類。也就是在工廠和產(chǎn)品之間增加界面,工廠不再負(fù)責(zé)產(chǎn)品的實(shí)現(xiàn),有借口針對不同條件返回不同的類實(shí)例,再由具體類實(shí)例去實(shí)現(xiàn)。工廠方法時(shí)簡單工廠的衍生,改進(jìn)了許多簡單工廠的缺點(diǎn),遵循了開——閉原則,實(shí)現(xiàn)了可擴(kuò)展,可以用于更為復(fù)雜的產(chǎn)品結(jié)果場合。工廠方法可以理解為同樣是父親給兒子留了一筆錢,然后直接讓兒子去支配,怎么花父親一律不管。
2.優(yōu)點(diǎn)
工廠方法模式客服了簡單工廠的很多缺點(diǎn),它每個(gè)具體工廠只完成單一任務(wù),而且遵循開——閉原則,代碼簡潔而且具有良好的擴(kuò)展性。
3.缺點(diǎn)
如果有產(chǎn)品類需要修改,對應(yīng)的工廠類也需要進(jìn)行修改。一旦有多個(gè)產(chǎn)品類都需要修改的時(shí)候,對號入座的問題就出現(xiàn)了,這是對工廠類的修改就會變得相當(dāng)復(fù)雜。因此工廠方法模式雖然有利于擴(kuò)展但是不利于維護(hù)。
綜上所述,我們就可以知道針對不同的情況具體采用哪種模式對編程更有利了。當(dāng)需要?jiǎng)?chuàng)建的對象比較少,客戶只知道傳入工廠的參數(shù),并不關(guān)心如何創(chuàng)建對象的時(shí)候就可以采用簡單工廠模式;當(dāng)類將創(chuàng)建對象的職責(zé)委托給多個(gè)幫助子類中的某一個(gè)時(shí)就可以采用工廠方法模式了。
相關(guān)文章
Qt利用QSortFilterProxyModel代理實(shí)現(xiàn)自定義排序與聯(lián)合過濾
QsortFilterProxyModel類用來為model和view之間提供強(qiáng)大的排序和過濾支持。這篇文章將利用QSortFilterProxyModel代理實(shí)現(xiàn)自定義排序與聯(lián)合過濾,需要的可以參考一下2022-11-11
C語言中網(wǎng)絡(luò)地址與二進(jìn)制數(shù)之間轉(zhuǎn)換的函數(shù)小結(jié)
這篇文章主要介紹了C語言中網(wǎng)絡(luò)地址與二進(jìn)制數(shù)之間轉(zhuǎn)換的函數(shù)小結(jié),是C語言入門學(xué)習(xí)中的基礎(chǔ)知識,需要的朋友可以參考下2015-09-09
C語言鏈表實(shí)現(xiàn)簡單圖書管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了C語言鏈表實(shí)現(xiàn)簡單圖書管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-03-03
C++高性能服務(wù)器框架之協(xié)程調(diào)度模塊
這篇文章主要介紹了C++高性能服務(wù)器框架中的協(xié)程調(diào)度模塊,文中通過代碼示例介紹的非常詳細(xì),對我們的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-06-06
二維指針動(dòng)態(tài)分配內(nèi)存連續(xù)問題深入分析
當(dāng)我們定義一個(gè)二維指針時(shí),如果需要存儲相應(yīng)的數(shù)據(jù),就需要我們動(dòng)態(tài)的分配內(nèi)存,這時(shí),有一點(diǎn)是需要注意的,分配內(nèi)存的方法不同,內(nèi)存的連續(xù)性也是不相同的2013-07-07
C++實(shí)現(xiàn)LeetCode(132.拆分回文串之二)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(132.拆分回文串之二),本篇文章通過簡要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
C++ Opencv imfill孔洞填充函數(shù)的實(shí)現(xiàn)思路與代碼
在Matlab下,使用imfill可以很容易的完成孔洞填充操作,下面這篇文章主要給大家介紹了關(guān)于C++ Opencv imfill孔洞填充函數(shù)的實(shí)現(xiàn)思路與代碼,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下2021-09-09
詳解state狀態(tài)模式及在C++設(shè)計(jì)模式編程中的使用實(shí)例
這篇文章主要介紹了state狀態(tài)模式及在C++設(shè)計(jì)模式編程中的使用實(shí)例,在設(shè)計(jì)模式中策略用來處理算法變化,而狀態(tài)則是透明地處理狀態(tài)變化,需要的朋友可以參考下2016-03-03

