C++設(shè)計(jì)模式編程中簡(jiǎn)單工廠與工廠方法模式的實(shí)例對(duì)比
簡(jiǎn)單工廠模式實(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)建其對(duì)應(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 : 定義控制臺(tái)應(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;
}
// 阻止控制臺(tái)進(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 : 定義控制臺(tái)應(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é)
首先無論是簡(jiǎn)單工廠模式還是工廠方法模式都是把不變的地方提取出來,把容易發(fā)生變化的封裝起來。以達(dá)到做大程度的復(fù)用,和適應(yīng)用戶的變動(dòng),以及項(xiàng)目的擴(kuò)展。
一、簡(jiǎn)單工廠模式
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è)具體類的對(duì)象。簡(jiǎn)單工廠模式可以理解為父親給兒子留了一筆錢,規(guī)定這筆錢可以用于上學(xué)、買房或者買車,然后讓兒子自己選擇用于哪一個(gè)。
2.優(yōu)點(diǎn)
工廠類包含必要的邏輯判斷,可以決定在什么時(shí)候創(chuàng)建哪一個(gè)類的實(shí)例,客戶端可以避免直接創(chuàng)建對(duì)象。這樣就可以實(shí)現(xiàn)對(duì)責(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)都會(huì)受到影響,可擴(kuò)展性較差。擴(kuò)展性差一旦有新的需求,就不得不修改工廠邏輯,這樣就會(huì)導(dǎo)致工廠邏輯過為復(fù)雜,違背了開——閉原則。同時(shí)靜態(tài)工廠方法不利于形成基于繼承的等級(jí)結(jié)構(gòu)。
二、工廠方法模式
1.理解
它是一個(gè)粒度很小的設(shè)計(jì)模式,因?yàn)槟J降谋憩F(xiàn)只是一個(gè)抽象的方法。工廠方法模式定義了一個(gè)用于創(chuàng)建對(duì)象的界面,讓子類決定具體實(shí)例化哪一個(gè)類。也就是在工廠和產(chǎn)品之間增加界面,工廠不再負(fù)責(zé)產(chǎn)品的實(shí)現(xiàn),有借口針對(duì)不同條件返回不同的類實(shí)例,再由具體類實(shí)例去實(shí)現(xiàn)。工廠方法時(shí)簡(jiǎn)單工廠的衍生,改進(jìn)了許多簡(jiǎn)單工廠的缺點(diǎn),遵循了開——閉原則,實(shí)現(xiàn)了可擴(kuò)展,可以用于更為復(fù)雜的產(chǎn)品結(jié)果場(chǎng)合。工廠方法可以理解為同樣是父親給兒子留了一筆錢,然后直接讓兒子去支配,怎么花父親一律不管。
2.優(yōu)點(diǎn)
工廠方法模式客服了簡(jiǎn)單工廠的很多缺點(diǎn),它每個(gè)具體工廠只完成單一任務(wù),而且遵循開——閉原則,代碼簡(jiǎn)潔而且具有良好的擴(kuò)展性。
3.缺點(diǎn)
如果有產(chǎn)品類需要修改,對(duì)應(yīng)的工廠類也需要進(jìn)行修改。一旦有多個(gè)產(chǎn)品類都需要修改的時(shí)候,對(duì)號(hào)入座的問題就出現(xiàn)了,這是對(duì)工廠類的修改就會(huì)變得相當(dāng)復(fù)雜。因此工廠方法模式雖然有利于擴(kuò)展但是不利于維護(hù)。
綜上所述,我們就可以知道針對(duì)不同的情況具體采用哪種模式對(duì)編程更有利了。當(dāng)需要?jiǎng)?chuàng)建的對(duì)象比較少,客戶只知道傳入工廠的參數(shù),并不關(guān)心如何創(chuàng)建對(duì)象的時(shí)候就可以采用簡(jiǎn)單工廠模式;當(dāng)類將創(chuàng)建對(duì)象的職責(zé)委托給多個(gè)幫助子類中的某一個(gè)時(shí)就可以采用工廠方法模式了。
上一篇:C++設(shè)計(jì)模式編程之Flyweight享元模式結(jié)構(gòu)詳解
欄 目:C語言
本文標(biāo)題:C++設(shè)計(jì)模式編程中簡(jiǎn)單工廠與工廠方法模式的實(shí)例對(duì)比
本文地址:http://www.jygsgssxh.com/a1/Cyuyan/2422.html
您可能感興趣的文章
- 04-02c語言沒有round函數(shù) round c語言
- 01-10深入理解C++中常見的關(guān)鍵字含義
- 01-10使用C++實(shí)現(xiàn)全排列算法的方法詳解
- 01-10c++中inline的用法分析
- 01-10用C++實(shí)現(xiàn)DBSCAN聚類算法
- 01-10全排列算法的非遞歸實(shí)現(xiàn)與遞歸實(shí)現(xiàn)的方法(C++)
- 01-10C++大數(shù)模板(推薦)
- 01-10淺談C/C++中的static與extern關(guān)鍵字的使用詳解
- 01-10深入C/C++浮點(diǎn)數(shù)在內(nèi)存中的存儲(chǔ)方式詳解
- 01-10深入理解C/C++混合編程


閱讀排行
- 1C語言 while語句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 04-02c語言函數(shù)調(diào)用后清空內(nèi)存 c語言調(diào)用
- 04-02func函數(shù)+在C語言 func函數(shù)在c語言中
- 04-02c語言的正則匹配函數(shù) c語言正則表達(dá)
- 04-02c語言用函數(shù)寫分段 用c語言表示分段
- 04-02c語言中對(duì)數(shù)函數(shù)的表達(dá)式 c語言中對(duì)
- 04-02c語言編寫函數(shù)冒泡排序 c語言冒泡排
- 04-02c語言沒有round函數(shù) round c語言
- 04-02c語言分段函數(shù)怎么求 用c語言求分段
- 04-02C語言中怎么打出三角函數(shù) c語言中怎
- 04-02c語言調(diào)用函數(shù)求fibo C語言調(diào)用函數(shù)求
隨機(jī)閱讀
- 04-02jquery與jsp,用jquery
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 01-10C#中split用法實(shí)例總結(jié)
- 01-10使用C語言求解撲克牌的順子及n個(gè)骰子
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 01-11ajax實(shí)現(xiàn)頁面的局部加載
- 01-10delphi制作wav文件的方法


