天天看点

【设计模式攻略】创建型模式之Factory method模式 【设计模式攻略】行为型模式之Template Method模式

概要 之前讨论过行为型模式之一的Template method模式,而Factory method模式其实是Template method模式在Factory场景(创建对象)下的一种应用形式。对Template method模式的定义是 在基类中为算法框架定义方法,通过该方法去调用子类中封装的算法各个步骤的具体实现,那么Factory method模式呢?其实就是一种具体的应用,我对它的定义是,在基类工厂中定义对象创建的总体框架逻辑,子类工厂中实现具体对象创建的步骤,然后通过基类方法去调用子类中封装的实际创建步骤。

目的 用户可以忽略对象具体实例化的逻辑过程,通过调用统一的接口来进行对象实例化,同时解除调用方与具体对象间的耦合,使调用者只依赖于抽象。(所有Factory模式的目的应该都一样)

实例 Factory method模式最基本的实现,如下:

class AbstractObject {};

class ConcreteObjectA : public AbstractObject {};
class ConcreteObjectB : public AbstractObject {};
class ConcreteObjectNULL : public AbstractObject {};
     
class Factory {
public:
     virtual AbstractObject* do_create() = 0;
     AbstractObject* create_object() {
          return      this->do_create();
     }
};

class FactoryA :public Factory{
public:
     virtual AbstractObject* do_create() {
          return new      ConcreteObjectA;
     }     
};

class FactoryB :public Factory{
public:
     virtual AbstractObject* do_create() {
          return new      ConcreteObjectB;
     }     
};
           

各个子类重写do_create方法来负责具体对象的创建,基类提供方法do_create方法来作为统一的对象创建接口。具体使用如下:

Factory* factory = new FactoryA;
AbstractObject* obj = factory->create_object();      // 获得ConcreteObjectA对象
           

看到这里,也许有人会问,这样做有什么实际的意义吗?不是把简单问题复杂化了吗?如果代码真的只是这样的话,确实是过于复杂化了。但是现实问题往往不是这么简单的,会有很多额外的需求。比如,我们假设所有对象具体有initialize方法,在对象创建同时需要保证initialize方法被调用来进行正常的初始化,又比如可能我们需要对ConcreteObjectA创建时添加额外的逻辑判断,等等等等,不同的对象创建初始化过程会接踵而至。基于上面的实现,我们简单扩展下就可以满足需求:

class AbstractObject {
public:
     virtual void initialize() {}     
};

class Factory {
public:
     virtual AbstractObject* do_create() = 0;
     AbstractObject* create_object() {
          AbstractObject* obj = this->do_create();
          obj->initialize();
          return      obj;
     }
};

class FactoryA :public Factory{
public:
     virtual AbstractObject* do_create() {
          bool isOk = true;
          // isOk = ...any judgement
          if (isOk)  
               return new      ConcreteObjectA;
          return new ConcreteObjectNULL;
     }     
};
           

而可以稍微想象一下,如果我们把所有创建逻辑都耦合在一个Factory类中时,会给以后的扩展带来很多麻烦。

应用 可以看出,Factory method是Template method模式的一种特例或一种应用方式。关于Template method模式请参考:

【设计模式攻略】行为型模式之Template Method模式