天天看点

【设计模式攻略】创建型模式之Abstract Factory模式

概要 Abstract factory模式其实就是普通factory模式的一种进化,它比较侧重于对一个系列中相关多个对象的创建工作。何谓一个系列?其实就是某种客观条件下满足特定需求的一组对象集合。当面对多个系列时,需要实现每个系列的实例化的Factory,这时使用一般的Factory模式往往让过程变得复杂,而Abstract factory模式则可以解决这类问题。

目的 Abstract factory模式可以提供统一的接口来创建一个系列的相关对象,而不需要显式的去指定每种对象类型。

实例 让我们来考虑一个实际的例子,假设我们有两款功放产品,每种功放有输入和输出两组module,我们要如何为这些module的实例化设计出一个可行又有效的方法?用Abstract factory就可以达到这个目的,考虑如下的类图:

【设计模式攻略】创建型模式之Abstract Factory模式

AbstractFactory类定义了一组创建功放输入和输出module的接口,具体的Factory类AmplifierFactory1和AmplifierFactory2负责具体功放的创建工作,Client可以通过AbstractFactory提供的接口来获得相应功放的输入输出对象。 代码的一般实现如下:

class AbstractAmplifierIn {};
class AbstractAmplifierOut {};

class Amplifer1_In : public AbstractAmplifierIn {};
class Amplifer2_In : public AbstractAmplifierIn {};
class Amplifer1_Out : public AbstractAmplifierOut {};
class Amplifer2_Out : public AbstractAmplifierOut {};

class AbstractFactory {
public:
     virtual AbstractAmplifierIn* create_amplifier_in() = 0;
     virtual AbstractAmplifierOut* create_amplifier_out() = 0;
};

class AmplifierFactory1 : public AbstractFactory {
public:
     AbstractAmplifierIn* create_amplifier_in() {
          return new Amplifer1_In;
     }
     AbstractAmplifierOut* create_amplifier_out() {
          return new Amplifer1_Out;
     }
};

class AmplifierFactory2 : public AbstractFactory {
public:
     AbstractAmplifierIn* create_amplifier_in() {
          return new Amplifer2_In;
     }
     AbstractAmplifierOut* create_amplifier_out() {
          return new Amplifer2_Out;
     }
};
           

可以通过相应的Factory类来创建相应的功放对象:

AbstractFactory* factory = new AmplifierFactory1;
AbstractAmplifierIn* amp_in = factory->create_amplifier_in();
AbstractAmplifierOut* amp_out = factory->create_amplifier_out();
           

另外,也可以与之前Factory模式一文中提出的一样,用map来注册和管理所有的工厂类对象,通过查询map来获得factory对象进而实例化相关对象,同时在AbstractFactory类中结合使用Singleton模式可以让实例化接口和使用更方便和统一。具体请参考: 【设计模式攻略】创建型模式之Factory模式

应用 现在应该能更容易理解,Abstract Factory模式更适用于提供统一的接口来创建一个系列的对象,如上例子中,所谓的一个系列就是一种功放的输入和输出模块。从接口的定义可以看出,用户只需要依赖抽象层的对象,而未耦合于具体实现,让对象的实例化和访问使用更加方便,当然具体使用的时候也有一点麻烦的地方,当功放还需要一种新的功能时,必须增加AbstractFactory的抽象接口和添加具体的实现,可以说是增加了一些额外的工作量。

继续阅读