对于在系统中创建并使用的对象,因为某些原因,比如需求变动,导致对象的具体实现发生了根本性的变化,但是在系统中,该对象所具有的接口,却表现出相对稳定的一致性(举例说来:比如系统使用的数据库因为需求变更,需要由原本使用的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. 命令规范在模式中的使用可以帮助你随时保持清晰头脑~~
参考资料:
《设计模式--可复用面向对象软件的基础》
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. 命令规范在模式中的使用可以帮助你随时保持清晰头脑~~
参考资料:
《设计模式--可复用面向对象软件的基础》