C++模板实现的通用工厂方法模式


1.工厂方法(Factory Method)模式

工厂方法模式的意义是定义一个创建产品对象的工厂接口,将实际创建工作推迟到子类当中。核心工厂类不再负责产品的创建,这样核心类成为一个抽象工厂角色,仅负责具体工厂子类必须实现的接口,这样进一步抽象化的好处是使得工厂方法模式可以使系统在不修改具体工厂角色的情况下引进新的产品。

工厂方法模式结构示意图

工厂方法模式是简单工厂模式的衍生,解决了许多简单工厂模式的问题。首先完全实现‘开-闭 原则’,实现了可扩展。其次更复杂的层次结构,可以应用于产品结果复杂的场合。

工厂方法模式很好用,但在代码层面上,为每一个产品都编写一个对应的工厂,这无疑很麻烦,而且不同的Product要写不同Creator。想想你在写一个GUI库,基本控件为Widget类,由其派生下了TextBox,Button,Label等几十个控件,那你需要为这几十个控件分别编写对应的ConcreteCreator。天,这太麻烦了吧!而如果你还要写一个RPG小游戏,需要从Person类派生下如NPC,Hero,Emeny,Ally等又是十几个类,而且还要编写一个对应于Person的Creator....

2.模板实现工厂方法模式

面对这种类型造成的多态,C++模板就要出场了。现在情况是这样的,Product和ConcreteProduct都已经写好,我们要为其编写对应的工厂类。可以看出来,Product对应对Creator,ConcreteProduct对应于ConcreteCreator。也就是说,如果想编写通用的ConcreteCreator,就得将ConcreteProduct抽象,想编写通用的Creator,就得将Product抽象。而我们最后会将这2者都抽象了。

首先编写通用的ConcreteCreator

  1. // 具体工厂类   
  2. // Product为抽象产品,ConcreteProduct为具体产品   
  3. template<typename Product, typename ConcreteProduct>  
  4. class ConcreteCreator  
  5. {  
  6. public:  
  7.     // 生产一个具体产品   
  8.     static Product* createProduct()  
  9.     {  
  10.         return new ConcreteProduct();  
  11.     }  
  12. };  

注意createProduct()是静态的,是因为该函数要被保存起来的,静态函数只需保存其函数指针即可,而普通的成员函数还要额外保存一个对象指针,这无疑更麻烦了。 也就是我们不需要这样用: 

  1. ConcreteCreator<Product, ConcreteProduct> concreteCreator;     
  2. Product* p = concreteCreator.createProduct();  

只需要这样写:

  1. Product* p = ConcreteCreator<Product, ConcreteProduct>::createProduct();  
  • 1
  • 2
  • 下一页

相关内容