对于在系统中创建并使用的对象,因为某些原因,比如需求变动,导致对象的具体实现发生了根本性的变化,但是在系统中,该对象所具有的接口,却表现出相对稳定的一致性(举例说来:比如系统使用的数据库因为需求变更,需要由原本使用的MySQL迁移到SQL Server上,这里数据库对象产生了根本性的变化,但是作为系统使用上来讲,对数据库的操作接口保持了稳定一致。工厂模式可有效的隔离对象的变化给系统代码所带来的影响。


结构图如下:


仍以上述的数据库对象的变化为例,给出说明代码。

首先给出抽象Product类,对应到是我们例子中就是关于SQL抽象类:
class ISql
{
public:
  virtual type Operations();  
}


而我们所需要ConcreteProduct类对应我们的Mysql,以及SQL Server类:


class CMysql: public ISql
{
public:
  CMysql(){}
  type Operations(){...}
}


class CSqlServer: ISql
{
public:
  CSqlServer(){}
  type Operations(){....}
}


类CMysql和CSqlServer继承自接口类ISql,各自实现了抽象的操作接口。

再看Creator抽象类 


class ICreator 

public: 
virtual ISql Create(); 



而ConcreteCreator对应CMysqlCreator和CSqlServerCreator类: 


class CMysqlCreator: public ICreator 

public: 
ISql Create(){return new CMysql();} 



class CSqlServerCreator: public ICreator 

public: 
ISql Create(){return new CSqlServer();} 



通过如上构建出工厂类后,当系统创建数据库对象形如: 


ICreator factory = new CMysqlCreator(); 
ISql database = factory.Create(); 


当需要改变数据库对象时,只需要将: 


ICreator factory = new CMysqlCreator(); 


改变为: 


ICreator factory = new CSqlServerCreator (); 


系统中其它部分的代码都不需要变动。由上述例子可以看出,工厂模式将具体的对象的创建工作延迟到了creator子类中,以此解少了系统同对象的耦合性,方便对系统进行扩展和修改。在将系统迁移至新的数据库时,不需要对抽象类进行改变,只需要增加新的数据库对象类和工厂类,再修改上面的那一行代码即可,就样就很好的符合了开放封闭原则。 


最后,按书中,给出使用工厂模式的三种时机: 


1. 当一个类不知道必须由它创建的对象的类的时候。 
2. 当一个类希望由它的子类来指定它所创建的对象的时候。 
3. 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望定位哪一个帮助子类是代理者时候。 


以及实现要点: 
1. Factory Method模式的两种情况:一是Creator类是一个抽象类且它不提供它所声明的工厂方法的实现;二是Creator是一个具体的类且它提供一个工厂方法的缺省实现。 
2. 工厂方法是可以带参数的。可以根据参数来对Creator所产生的对象进行扩展和修改。 
3.C++中使用模板可以避免子类化。 
4. 命令规范在模式中的使用可以帮助你随时保持清晰头脑~~ 


参考资料: 
《设计模式--可复用面向对象软件的基础》