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(运算符工厂类)

/************************************************************************/
/* 运算符工厂类 */
/************************************************************************/
#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(运算符基类)

#include "stdafx.h"
#include "COperation.h" 

COperation::COperation()
  : _dNumA(0)
  , _dNumB(0)
{ 

}

COperation.h

/************************************************************************/
/* 运算符基类 */
/************************************************************************/ 

#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)

/************************************************************************/
/* 加法运算符子类,继承于运算符基类 */
/************************************************************************/
#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)

/************************************************************************/
/* 除法运算符子类,继承于运算符基类 */
/************************************************************************/
#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)

/************************************************************************/
/* 乘法运算符子类,继承于运算符基类 */
/************************************************************************/
#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)

/************************************************************************/
/* 减法运算符子类,继承于运算符基类 */
/************************************************************************/
#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(客户端应用类,主函数所在)

// 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

/************************************************************************/
/* 抽象水果类(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)具体产品类

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 : 定义控制台应用程序的入口点。
// 

#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.缺点

如果有产品类需要修改,对应的工厂类也需要进行修改。一旦有多个产品类都需要修改的时候,对号入座的问题就出现了,这是对工厂类的修改就会变得相当复杂。因此工厂方法模式虽然有利于扩展但是不利于维护。

综上所述,我们就可以知道针对不同的情况具体采用哪种模式对编程更有利了。当需要创建的对象比较少,客户只知道传入工厂的参数,并不关心如何创建对象的时候就可以采用简单工厂模式;当类将创建对象的职责委托给多个帮助子类中的某一个时就可以采用工厂方法模式了。

(0)

相关推荐

  • 深入解析C++设计模式编程中解释器模式的运用

    解释器模式(interpreter),给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 解释器模式需要解决的是,如果一种特定类型的问题发生的频率足够高,那么可能就值得将该问题的各个实例表述为一个简单语言中的句子.这样就可以构建一个解释器,该解释器通过解释这些句子来解决该问题.当有一个语言需要解释执行,并且你可将该语言中的句子表示为一个抽象语法树时,可使用解释器模式.用了解释器模式,就意味着可以很容易地改变和扩展文法,因为该模式使用类来表示文法规则,

  • 解析C++编程中如何使用设计模式中的状态模式结构

    作用:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类. UML图如下: State类,抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为. ConcreteState类,具体状态,每一个子类实现一个与Context的一个状态相关的行为. Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态. 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况.把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把

  • C++设计模式编程中使用Bridge桥接模式的完全攻略

    桥接模式将抽象(Abstraction)与实现(Implementation)分离,使得二者可以独立地变化. 桥接模式典型的结构图为: 在桥接模式的结构图中可以看到,系统被分为两个相对独立的部分,左边是抽象部分,右边是实现部分,这两个部分可以互相独立地进行修改:例如上面问题中的客户需求变化,当用户需求需要从 Abstraction 派生一个具体子类时候,并不需要像上面通过继承方式实现时候需要添加子类 A1 和 A2 了.另外当上面问题中由于算法添加也只用改变右边实现(添加一个具体化子类),而右边

  • 详解设计模式中的中介者模式在C++编程中的运用

    作用:用一个中介对象来封装一系列的对象交互.中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互. 结构图如下: Colleage抽象同事类,而ConcreteColleage是具体同时类,每个具体同事只知道自己的行为,而不了解其他同事类的情况,但它们却都认识中介者对象,Mediator是抽象中介者,定义了同事对象到中介者对象的接口,ConcreteMediator是具体中介者对象,实现抽象类的方法,它需要知道所有具体同事类,并从具体同事接受消息,向具体同事对象

  • 实例讲解C++设计模式编程中State状态模式的运用场景

    State模式允许一个对象在其内部状态改变时改变它的行为.对象看起来似乎修改了它的类. 在面向对象系统的开发和设计过程,经常会遇到一种情况就是需求变更(Requirement Changing),经常我们做好的一个设计.实现了一个系统原型,咱们的客户又会有了新的需求.我们又因此不得不去修改已有的设计,最常见就是解决方案就是给已经设计.实现好的类添加新的方法去实现客户新的需求,这样就陷入了设计变更的梦魇:不停地打补丁,其带来的后果就是设计根本就不可能封闭.编译永远都是整个系统代码. 访问者模式则提

  • 详解设计模式中的Command命令模式及相关C++实现

    命令模式的作用是将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤销的操作. 由于"行为请求者"与"行为实现者"的紧耦合,使用命令模式,可以对请求排队或记录请求日志,以及支持可撤销的操作. 命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开. Command模式关键就是讲一个请求封装到一个类中(Command),再提供处理对象(Receiver),最后Command命令由Invoker激活.另外,我们

  • C++设计模式编程之Flyweight享元模式结构详解

    由遇到的问题引出享元模式: 在面向对象系统的设计何实现中,创建对象是最为常见的操作.这里面就有一个问题:如果一个应用程序使用了太多的对象,就会造成很大的存储开销.特别是对于大量轻量级(细粒度)的对象,比如在文档编辑器的设计过程中,我们如果为没有字母创建一个对象的话,系统可能会因为大量的对象而造成存储开销的浪费.例如一个字母"a"在文档中出现了100000 次,而实际上我们可以让这一万个字母"a"共享一个对象,当然因为在不同的位置可能字母"a"有不

  • 设计模式中的备忘录模式解析及相关C++实例应用

    备忘录模式旨在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态.这样以后就可将该对象恢复到原先保存的状态.在命令模式中,备忘录模式经常还经常被用来维护可以撤销(Undo)操作的状态. 类图: Originator:负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态.Originator可根据需要决定Memento存储Originator的哪些内部状态. Memento:负责存储Originator对象的内部状态,并可防止Origin

  • 详解C++设计模式编程中对访问者模式的运用

    访问者模式(visitor),表示一个作用于某对象结构中的各元素的操作.它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作.访问者模式适用于数据结构相对稳定的系统.它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化.访问者模式的目的是要把处理从数据结构分离出来.很多系统可以按照算法和数据结构分开,如果这样的系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就是比较合适的,因为访问者模式使得算法操作的增加变得容易.反之,如果这样的系统的数据结

  • 详解C++设计模式编程中责任链模式的应用

    职责链模式:使多个对象都有机会处理请求,从而避免请求的发送者和接收者之间的耦合关系.将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它为止. 其思想很简单,比如考虑员工要求加薪.公司的管理者一共有三级,总经理.总监.经理,如果一个员工要求加薪,应该向主管的经理申请,如果加薪的数量在经理的职权内,那么经理可以直接批准,否则将申请上交给总监.总监的处理方式也一样,总经理可以处理所有请求.这就是典型的职责链模式,请求的处理形成了一条链,直到有一个对象处理请求.给出这个例子的UML图.

随机推荐