[设计模式攻略]创建型模式之Factory模式

2014-11-24 02:50:25 · 作者: · 浏览: 0
概要 Factory模式在现代 编程语言中应该也是使用最广泛的模式之一。Factory模式有很多变体,根据实际情况,实现形式多样。最常见的可能还是GOF中提出的Abstract Factory模式和Factory Method模式。本文只是从最基本的Facotry模式概念本身出发,看看抛开GOF提出的两种经典Factory模式不谈,现阶段常见Factory模式的实现形式,在后续的其他文章中会再跟大家重点讨论GOF提出的Abstract Factory和Factory Method这两种模式。 Factory模式,顾名思义,就是抽象和封装了实例化动作的工厂,提供尽可能统一的接口给用户,简化对象的实例化过程。
目的 用户可能忽略对象具体实例化的逻辑过程,通过调用统一的接口来进行对象实例化,同时解除调用方与具体对象间的耦合,使调用者只依赖于抽象。
实例 看一种最简单的Factory模式的实现,假设有一组对象ConcreteObjectA,ConcreteObjectB,Factory负责对象的实例化,类图: \
代码实现如下:
class AbstractObject {};

class ConcreteObjectA : public AbstractObject {};
class ConcreteObjectB : public AbstractObject {};
class ConcreteObjectNULL : public AbstractObject {};
    
class Factory {
public:
     AbstractObject* create_object(const string& type) {
          if (type == "A") {
               return new      ConcreteObjectA;
          } else if type == "B") {
               return new      ConcreteObjectB;
          }
          return new ConcreteObjectNULL;
     }
};
用户可以通过统一的方法create_object,指定类型来实例化相应的对象:
Factory factory;
AbstractObject* obj_A = factory.create_object("A");
AbstractObject* obj_B = factory.create_object("B");
为了让Factory类使用更简单,可以Singleton模式来包装Factory类,Singleton模式请参考我的上一篇文章: 【设计模式攻略】创建型模式之Singleton模式(也谈勿滥用Singleton)
虽然这种Factory模式的实现很简单,没什么技术含量,但在很多程序中还是会被经常用到,就因为两个字,简单! 也许有人会说,那如果每添加一种对象,就需要修改Factory类,在其中增加相应对象的创建,那不是违反了Open-Close原则?Open-Close原则请参考: 【设计模式攻略】OO设计原则之OCP-开放-关闭原则 确实没错,那我们稍微改变下Factory的实现: \
为每个具体对象构造一个相应的Factory,在基类Factory中创建一个map,维护所有需要的Factory,每个子类Factory在构造函数中把自己注册到factory map中,具体对象由其对应的Factory来负责创建(重写do_create方法),代码如下:
class Factory {
public:
     AbstractObject* create_object(const string& type) {
          std::map
  
   ::iterator it;
          it = factory_map.find(type);
          if (it != factory_map.end()) {
               return factory_map[type]->do_create();
          }
          return factory_map["NULL"]->do_create();
     }
    
     void register_factory(const string& type, Factory* factory) {
          factory_map[type] = factory;
     }
private:
     virtual AbstractObject* do_create() = 0;
     static std::map
   
     factory_map; }; class FactoryA :public Factory{ public: FactoryA() { register_factory("A", this); } virtual AbstractObject* do_create() { return new ConcreteObjectA; } }; class FactoryB :public Factory{ public: FactoryB() { register_factory("B", this); } virtual AbstractObject* do_create() { return new ConcreteObjectB; } }; class FactoryNULL :public Factory{ public: FactoryNULL() { register_factory("NULL", this); } virtual AbstractObject* do_create() { return new ConcreteObjectNULL; } };
   
  

用户使用时,首先需要定义所有的Factory对象,然后通过Factory的create_object方法来创建相应对象:
FactoryA factory_A;
FactoryB factory_B;
FactoryNULL factory_NULL;
// 以上对象的定义一般作为全局对象定义在对应Factory类实现的cpp文件中
注意一般会用Singleton来包装Factory,使用更方便,这里为了简化实现过程,没有采用Singleton
Factory factory;
AbstractObject* obj_A = factory.create_object("A");
AbstractObject* obj_B = factory.create_object("B");
相较于第一种实现,当要增加具体对象ConcreteObjectC时,不再需要修改Factory类本身,只需要增加FactoryC,并在代码定义FactoryC类型的对象factory_C后就可以了,满足开闭原则的要求。
我开始曾描述第二种实现是改变了第一种Factory的实现,而没有说是改进。因为两种实现确实各有利弊,对于第二种实现虽然从OO设计的角度更理想,但是却也带来了一下问题: 1. 每个Factory必须在使用前都各自实例化 2. 实现变得更复杂 3. 没多一种对象需要增加一个新的Factory类 当然,在使用 Java或其他语言实现时,可以避免一些C++实现的难点,让实现更简单。
应用 Factory模式是使用最广泛的设计模式之一,可以说稍微有点规模的程序里都充实着各种形式的Factory,当用C++来实现时,需要额外注意一些问题,比如如果需要对象销毁怎么做,对象生命周期的管理等等。