一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - C++設計模式編程中簡單工廠與工廠方法模式的實例對比

C++設計模式編程中簡單工廠與工廠方法模式的實例對比

2021-03-29 10:58freshow C/C++

這篇文章主要介紹了C++設計模式編程中簡單工廠與工廠方法模式的實例對比,文中最后對兩種模式的優缺點總結也比較詳細,需要的朋友可以參考下

簡單工廠模式實例
題目:實現計算器的輸入2個數和運算符,得到結果

工程結構:

(1)頭文件

COperationFactory.h(運算符工廠類)

(2)源文件

SimpleFactory.cpp(客戶端應用類,主函數所在)

(3)運算類

COperation.cpp(運算符基類)
COperation.h
COperationAdd.h(加法運算符子類,繼承于COperation)
COperationDiv.h (除法運算符子類,繼承于COperation)
COperationMul.h (乘法運算符子類,繼承于COperation)
COperationSub.h(減法運算符子類,繼承于COperation)

=============  代碼實現部分 =============

COperationFactory.h(運算符工廠類)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/************************************************************************/
/* 運算符工廠類 */
/************************************************************************/
#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(){};
 
  // 根據入參的不同,創建其對應的運算符類指針。就像是個工廠,創建用戶指定的運算符類指針
  static COperation* NewOperation(const string& strOperate)
  {
    // 入參合法性判斷,防止后面的strOperate[0]發生越界訪問
    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(運算符基類)

?
1
2
3
4
5
6
7
8
9
#include "stdafx.h"
#include "COperation.h"
 
COperation::COperation()
  : _dNumA(0)
  , _dNumB(0)
{
 
}

COperation.h

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
/************************************************************************/
/* 運算符基類 */
/************************************************************************/
 
#ifndef _COPERATION_H_
#define _COPERATION_H_
 
class COperation
{
public:
  COperation();
  ~COperation(){};
     
  // 設置被運算數
  void SetNumA(double dNumA)
  {
    _dNumA = dNumA;
  };
   
  // 獲取被運算數
  double GetNumA()
  {
    return _dNumA;
  };
 
  // 設置運算數
  void SetNumB(double dNumB)
  {
    _dNumB = dNumB;
  };
 
  // 獲取運算數
  double GetNumB()
  {
    return _dNumB;
  };
 
  // 計算結果且在子類中實現各自的運算方法結果
  virtual double Result()
  {
    double dResult = 0;
    return dResult;
  }
 
private:
  double _dNumA;
  double _dNumB;
};
 
#endif _COPERATION_H_

COperationAdd.h(加法運算符子類,繼承于COperation)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/************************************************************************/
/* 加法運算符子類,繼承于運算符基類 */
/************************************************************************/
#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 (除法運算符子類,繼承于COperation)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/************************************************************************/
/* 除法運算符子類,繼承于運算符基類 */
/************************************************************************/
#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 (乘法運算符子類,繼承于COperation)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/************************************************************************/
/* 乘法運算符子類,繼承于運算符基類 */
/************************************************************************/
#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(減法運算符子類,繼承于COperation)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/************************************************************************/
/* 減法運算符子類,繼承于運算符基類 */
/************************************************************************/
#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(客戶端應用類,主函數所在)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// SimpleFactory.cpp : 定義控制臺應用程序的入口點。
//
 
#include "stdafx.h"
#include "COperationFactory.h"
 
int _tmain(int argc, _TCHAR* argv[])
{  
  // 通過運算符工廠創建加法運算
  COperation* OperAdd = COperationFactory::NewOperation("+");
  if (NULL != OperAdd)
  {
    OperAdd->SetNumA(168); // 設置被加數
    OperAdd->SetNumB(105); // 設置加數    
    cout << "168 + 105 = " << (OperAdd->Result()) << endl;
  }
 
  // 通過運算符工廠創建減法運算
  COperation* OperSub = COperationFactory::NewOperation("-");
  if (NULL != OperSub)
  {
    OperSub->SetNumA(168); // 設置被減數
    OperSub->SetNumB(105); // 設置減數    
    cout << "168 - 105 = " << (OperSub->Result()) << endl;
  }
 
  // 通過運算符工廠創建乘法運算
  COperation* OperMul = COperationFactory::NewOperation("*");
  if (NULL != OperMul)
  {
    OperMul->SetNumA(168); // 設置被乘數
    OperMul->SetNumB(105); // 設置乘數    
    cout << "168 * 105 = " << (OperMul->Result()) << endl;
  }
 
  // 通過運算符工廠創建除法運算
  COperation* OperDiv = COperationFactory::NewOperation("/");
  if (NULL != OperDiv)
  {
    OperDiv->SetNumA(168); // 設置被除數
    OperDiv->SetNumB(105); // 設置除數    
    cout << "168 / 105 = " << (OperDiv->Result()) << endl;
     
    OperDiv->SetNumB(0);  // 改變除數
    cout << (OperDiv->Result()) << endl;
  }
 
  // 阻止控制臺進程結束,便于查看結果
  int nEnd = 0;
  cin >> nEnd;
 
  return 0;
}

抽象工廠模式實例

工程結構:

(1)抽象產品類

IFruit.h

(2)抽象工廠類

IFruitGardener.h

(3)具體產品類

CApple.h

CGrape.h

CStrawberry.h

(4)具體工廠類

CAppleGardener.h

CGrapeGardener.h

CStrawberryGardener.h

(5)客戶端

FactoryMethodApplication.cpp

(1)抽象產品類

IFruit.h

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/************************************************************************/
/* 抽象水果類(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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/************************************************************************/
/* 抽象水果園丁類(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)具體產品類

CApple.h

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/************************************************************************/
/* 具體的蘋果類(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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/************************************************************************/
/* 具體的葡萄類(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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
/************************************************************************/
/* 具體的草莓類(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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/************************************************************************/
/* 具體的蘋果園丁類(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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/************************************************************************/
/* 具體的葡萄園丁類(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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/************************************************************************/
/* 具體的草莓園丁類(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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// FactoryMethodApplication.cpp : 定義控制臺應用程序的入口點。
//
 
#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;
}

 

總結

首先無論是簡單工廠模式還是工廠方法模式都是把不變的地方提取出來,把容易發生變化的封裝起來。以達到做大程度的復用,和適應用戶的變動,以及項目的擴展。

一、簡單工廠模式

1.理解

又稱為靜態工廠模式,它專門定義一個類來負責創建其他類的實例,被創建的實例通常都具有相通的父類。由工廠類根據傳入的參數動態決定應該創建哪一個產品類的實例。它包含必要的判斷邏輯,能根據外界給定的信息,決定應該穿件那個具體類的對象。簡單工廠模式可以理解為父親給兒子留了一筆錢,規定這筆錢可以用于上學、買房或者買車,然后讓兒子自己選擇用于哪一個。

2.優點

工廠類包含必要的邏輯判斷,可以決定在什么時候創建哪一個類的實例,客戶端可以避免直接創建對象。這樣就可以實現對責任的分割,降低耦合性,明確了具體的職責和權力,有利于整個系統的優化。

3.缺點

當產品具有比較復雜的多層結構時,它的工廠類只有一個,這時候再以不變應萬變就成為它最大的缺點了。因為工廠類是整個組織的核心,它聚集了所有產品的創建邏輯,一旦工廠不能正常工作,整個系統都會受到影響,可擴展性較差。擴展性差一旦有新的需求,就不得不修改工廠邏輯,這樣就會導致工廠邏輯過為復雜,違背了開——閉原則。同時靜態工廠方法不利于形成基于繼承的等級結構。

二、工廠方法模式

1.理解

它是一個粒度很小的設計模式,因為模式的表現只是一個抽象的方法。工廠方法模式定義了一個用于創建對象的界面,讓子類決定具體實例化哪一個類。也就是在工廠和產品之間增加界面,工廠不再負責產品的實現,有借口針對不同條件返回不同的類實例,再由具體類實例去實現。工廠方法時簡單工廠的衍生,改進了許多簡單工廠的缺點,遵循了開——閉原則,實現了可擴展,可以用于更為復雜的產品結果場合。工廠方法可以理解為同樣是父親給兒子留了一筆錢,然后直接讓兒子去支配,怎么花父親一律不管。

2.優點

工廠方法模式客服了簡單工廠的很多缺點,它每個具體工廠只完成單一任務,而且遵循開——閉原則,代碼簡潔而且具有良好的擴展性。

3.缺點

如果有產品類需要修改,對應的工廠類也需要進行修改。一旦有多個產品類都需要修改的時候,對號入座的問題就出現了,這是對工廠類的修改就會變得相當復雜。因此工廠方法模式雖然有利于擴展但是不利于維護。

綜上所述,我們就可以知道針對不同的情況具體采用哪種模式對編程更有利了。當需要創建的對象比較少,客戶只知道傳入工廠的參數,并不關心如何創建對象的時候就可以采用簡單工廠模式;當類將創建對象的職責委托給多個幫助子類中的某一個時就可以采用工廠方法模式了。

延伸 · 閱讀

精彩推薦
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
主站蜘蛛池模板: 日韩精选视频 | 2019年国产高清情侣视频 | 亚洲国产AV无码综合在线 | 99热免费在线观看 | 2018久久精品热在线观看 | 91污污视频| 72张让男人一看就硬的图片 | 大伊香蕉精品二区视频在线 | 天天干夜夜添 | 美女的让男人桶爽免费看 | 国产小视频在线免费 | 俺去啦最新地址 | 任我行视频在线观看国语 | 超级碰碰免费视频 | 亚洲精品午夜在线观看 | 亚洲成色www久久网站 | 精品国产一区二区三区久 | 日韩欧美亚洲天堂 | 日本视频免费在线观看 | 亚洲国产欧美在线成人aaaa | 欧美一区精品二区三区 | 婷婷99视频精品全部在线观看 | 亚洲 欧美 日韩 综合 | 亚洲国产高清视频 | 免费观看欧美成人h | 国产成人精品高清在线观看99 | 亚洲男人天堂网站 | 四虎影院永久网址 | 国产精品日本一区二区三区在线看 | 久久视频在线视频 | 亚洲免费二区 | 九九爱这里只有精品 | 无码人妻视频又大又粗欧美 | 欧美一级裸片又黄又裸 | 女张腿男人桶羞羞漫画 | 日本亚欧乱色视频在线观看 | 色亚洲视频 | 国产亚洲一欧美一区二区三区 | 四虎成人免费观看在线网址 | 日本在线观看a | 亚洲精品tv久久久久久久久久 |