举例解析设计模式中的工厂方法模式在C++编程中的运用

工厂方法模式不同于简单工厂模式的地方在于工厂方法模式把对象的创建过程放到里子类里。这样工厂父对象和产品父对象一样,可以是抽象类或者接口,只定义相应的规范或操作,不涉及具体的创建或实现细节。
其类图如下:

实例代码为:

#pragma once
class IProduct
{
public:
  IProduct(void);
  virtual ~IProduct(void);
}; 

#pragma once
#include "iproduct.h"
class IPad :
  public IProduct
{
public:
  IPad(void);
  ~IPad(void);
}; 

#pragma once
#include "iproduct.h"
class IPhone :
  public IProduct
{
public:
  IPhone(void);
  ~IPhone(void);
}; 

#pragma once
#include"IProduct.h" 

class IFactory
{
public:
  IFactory(void);
  virtual ~IFactory(void); 

  virtual IProduct* getProduct();
}; 

#pragma once
#include "ifactory.h"
class IPadFactory :
  public IFactory
{
public:
  IPadFactory(void);
  ~IPadFactory(void); 

  virtual IProduct* getProduct();
}; 

#pragma once
#include "ifactory.h"
class IPhoneFactory :
  public IFactory
{
public:
  IPhoneFactory(void);
  ~IPhoneFactory(void); 

  virtual IProduct* getProduct();
};

关键的实现:

#include "StdAfx.h"
#include "IPadFactory.h"
#include"IPad.h" 

IPadFactory::IPadFactory(void)
{
} 

IPadFactory::~IPadFactory(void)
{
} 

IProduct* IPadFactory::getProduct()
{
  return new IPad();
} 

#include "StdAfx.h"
#include "IPhoneFactory.h"
#include"IPhone.h" 

IPhoneFactory::IPhoneFactory(void)
{
} 

IPhoneFactory::~IPhoneFactory(void)
{
} 

IProduct* IPhoneFactory::getProduct()
{
  return new IPhone();
}

调用方式:

#include "stdafx.h"
#include"IFactory.h"
#include"IPadFactory.h"
#include"IPhoneFactory.h"
#include"IProduct.h" 

int _tmain(int argc, _TCHAR* argv[])
{
  IFactory *fac = new IPadFactory();
  IProduct *pro = fac->getProduct(); 

  fac = new IPhoneFactory();
  pro = fac->getProduct();
  return 0;
}

应用场景:
1..net里面的数据库连接对象就是产生数据命令对象的工厂。每种数据库的connection对象里(继承自IDbConnection)都有对自己createCommand(定义在IDbCommand里)的实现。
2..net里面的迭代器,IEnumerable定义了迭代器的接口,即工厂方法,每一个继承自IEnumerable的类都要实现GetEnumerator。可以参看ArrayList,String的GetEnumerator方法。他们都继承自IEnumerable。

对比简单工厂模式与工厂方法模式:

1. 结构复杂度

从这个角度比较,显然简单工厂模式要占优。简单工厂模式只需一个工厂类,而工厂方法模式的工厂类随着产品类个数增加而增加,这无疑会使类的个数越来越多,从而增加了结构的复杂程度。

2.代码复杂度

代码复杂度和结构复杂度是一对矛盾,既然简单工厂模式在结构方面相对简洁,那么它在代码方面肯定是比工厂方法模式复杂的了。简单工厂模式的工厂类随着产品类的增加需要增加很多方法(或代码),而工厂方法模式每个具体工厂类只完成单一任务,代码简洁。

3.客户端编程难度

工厂方法模式虽然在工厂类结构中引入了接口从而满足了OCP,但是在客户端编码中需要对工厂类进行实例化。而简单工厂模式的工厂类是个静态类,在客户端无需实例化,这无疑是个吸引人的优点。

4.管理上的难度

这是个关键的问题。

我 们先谈扩展。众所周知,工厂方法模式完全满足OCP,即它有非常良好的扩展性。那是否就说明了简单工厂模式就没有扩展性呢?答案是否定的。简单工厂模式同 样具备良好的扩展性——扩展的时候仅需要修改少量的代码(修改工厂类的代码)就可以满足扩展性的要求了。尽管这没有完全满足OCP,但笔者认为不需要太拘 泥于设计理论。

然后我们从维护性的角度分析下。假如某个具体产品类需要进行一定的修改,很可能需要修改对应的工厂类。当同时 需要修改多个产品类的时候,对工厂类的修改会变得相当麻烦(对号入座已经是个问题了)。反而简单工厂没有这些麻烦,当多个产品类需要修改是,简单工厂模式 仍然仅仅需要修改唯一的工厂类(无论怎样都能改到满足要求吧?大不了把这个类重写)。

由以上的分析,笔者认为简单工厂模式更好用更方便些。当然这只是笔者的个人看法而已,毕竟公认的,工厂方法模式比简单工厂模式更“先进”。但有时过于先进的东西未必适合自己,这个见仁见智吧。

(0)

相关推荐

  • 深入解析C++编程中对设计模式中的策略模式的运用

    策略模式也是一种非常常用的设计模式,而且也不复杂.下面我们就来看看这种模式. 定义:策略模式定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法独立于使用它的客户而独立变化. 角色: 抽象策略角色(Strategy): 抽象策略类. 具体策略角色(ConcreteStrategy):封装了继续相关的算法和行为. 环境角色(Context):持有一个策略类的引用,最终给客户端调用. UML图: 例子: #include <iostream> using names

  • 实例讲解C++编程中对设计模式中的原型模式的使用

    原型模式的实现完整代码示例(code):原型模式的实现很简单,这里为了方便初学者的学习和参考,将给出完整的实现代码(所有代码采用 C++实现,并在 VC 6.0 下测试运行). 代码片断 1:Prototype.h //Prototype.h #ifndef _PROTOTYPE_H_ #define _PROTOTYPE_H_ class Prototype{ public: virtual ~Prototype(); virtual Prototype* Clone() const = 0;

  • C++设计模式编程中proxy代理模式的使用实例

    代理模式典型的结构图为: 实际上,代理模式的想法非常简单. 代理模式的实现: 完整代码示例(code):代理模式的实现很简单,这里为了方便初学者的学习和参考,将给出完整的实现代码(所有代码采用 C++实现,并在 VC 6.0 下测试运行). 代码片断 1:Proxy.h //Proxy.h #ifndef _PROXY_H_ #define _PROXY_H_ class Subject{ public: virtual ~Subject(); virtual void Request() =

  • 解析设计模式中的Prototype原型模式及在C++中的使用

    原型模式的意图是用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象. 适用性  当要实例化的类是在运行时刻指定时,例如,通过动态装载:或者 为了避免创建一个与产品类层次平行的工厂类层次时:或者 当一个类的实例只能有几个不同状态组合中的一种时.建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些. 关于这个模式,突然想到了小时候看的<西游记>,齐天大圣孙悟空再发飙的时候可以通过自己头上的 3 根毛立马复制出来成千上万的孙悟空,对付小妖怪很管用(数量最重要). 原

  • C++编程中使用设计模式中的policy策略模式的实例讲解

    在看<C++设计新思维>的时候,发现在一开始就大篇幅的介绍策略模式(policy),策略模式不属于经典设计模式中的一种,但是其实在我们日常的开发中是必不可少的.policy,策略,方针,这里的意思是指把复杂功能的类尽量的拆分为功能单一的简单类的组合,简单的类只负责单纯行为或结构的某一方面.增加程序库的弹性,可复用性,可扩展性.policy是一个虚拟的概念,他定义了某一类class的一些接口规范,并不与C++语法的关键字对应,只是一个抽象的概念. 实例1: //policy模式的常见使用实例sm

  • 详解C++设计模式编程中建造者模式的实现

    建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示.这是建造者模式的标准表达,不过看着让人迷惑,什么叫构建和表示的分离?一个对象使用构造函数构造之后不就固定了,只有通过它方法来改变它的属性吗?而且还要同样的构建过程搞出不同的表示,怎么可能呢?多写几个构造函数? 其实多写几个构造函数,根据不同参数设置对象不同的属性,也可以达到这样的效果,只是这样就非常麻烦了,每次要增加一种表示就要添加一个构造函数,将来构造函数会多得连自己都不记得了,这违背了开放-封闭的原则. 要

  • 详解C++设计模式编程中策略模式的优缺点及实现

    策略模式(Strategy):它定义了一系列的算法,并将每一个算法封装起来,而且使它们还可以相互替换.策略模式让算法的变化不会影响到使用算法的客户.策略模式和 Template 模式要解决的问题是相同(类似)的,都是为了给业务逻辑(算法)具体实现和抽象接口之间的解耦.策略模式将逻辑(算法)封装到一个类(Context)里面,通过组合的方式将具体算法的实现在组合对象中实现,再通过委托的方式将抽象接口的实现委托给组合对象实现.State 模式也有类似的功能,他们之间的区别将在讨论中给出. UML图

  • 详解设计模式中的模板方法模式及在C++中的使用

    模板方法模式是设计模式行为型中最简单的一种设计模式.在实际中你甚至可能经常用到,只是你自己不知道它是一种设计模式罢了. 模板方法模式定义一个操作中的算法的骨架,而将一些步骤延迟到子类中.模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤. 角色: 抽象类(AbstractClass): 定义抽象的原语操作,具体的子类将重定义它们以实现一个算法,实现一个模板方法,定义一个算法的骨架.该模板方法不仅调用原语操作,也调用定义 具体子类 (ConcreteClass): 实现原语操作

  • 简单了解设计模式中的装饰者模式及C++版代码实现

    由遇到的问题引出的装饰模式 在 OO 设计和开发过程,可能会经常遇到以下的情况:我们需要为一个已经定义好的类添加新的职责(操作),通常的情况我们会给定义一个新类继承自定义好的类,这样会带来一个问题(将在本模式的讨论中给出).通过继承的方式解决这样的情况还带来了系统的复杂性,因为继承的深度会变得很深. 而装饰提供了一种给类增加职责的方法,不是通过继承实现的,而是通过组合. 有关这些内容在讨论中进一步阐述. 模式选择 装饰模式典型的结构图为: 在 结 构 图 中 , ConcreteComponen

  • 浅析设计模式中的代理模式在C++编程中的运用

    由遇到的问题引出代理模式 至少在以下集中情况下可以用代理模式解决问题: 创建开销大的对象时候,比如显示一幅大的图片,我们将这个创建的过程交给代理去完成,GoF 称之为虚代理(Virtual Proxy): 为网络上的对象创建一个局部的本地代理,比如要操作一个网络上的一个对象(网络性能不好的时候,问题尤其突出),我们将这个操纵的过程交给一个代理去完成,GoF 称之为远程代理(Remote Proxy): 对对象进行控制访问的时候,比如在 Jive 论坛中不同权限的用户(如管理员.普通用户等)将获得

随机推荐