最近写TLibrary,有了很多软件架构方面的思考,也觉得自己在这方面理论知识的不足,从网上down了一本电子书,就叫design pattern,它介绍了很多相关的设计模式,觉得收获很大,不过,这本书有个缺点,就是叙述过于枯燥,实在不适合阅读,应该是说是一本不错的Reference book,我想在这里写写我自己学习的体会和理解,有可能不准确,请大家指正,另外部分文字摘自《design pattern》,就此声明
抽象工厂(Abstract Factory)
设计模式里的工厂,是指一种创建对象的接口,抽象工厂则定义了一组用来创建抽象对象的接口,举个例子,对于下面一组对象
{}
class ProductA : public Product
{}
class ProductB : public Product
{}
我们按照通常的方式创建对象,则硬编码了Product的具体实现,比如我们要实现窗口换肤,这样的编码方式会非常不方便扩展
Product * pB = new ProductB;
现在我们用抽象工厂的方式来创建对象,我们定义一个虚方法CreateProduct来负责创建相应的对象
{
virtual Product * CreateProduct()
{
return new Product;
}
}
class ProductAFactory
{
virtual Product * CreateProduct()
{
return new ProductA;
}
}
class ProductBFactory
{
virtual Product * CreateProduct()
{
return new ProductB;
}
}
这样我们就可以用下面的方式来创建对象啦,虽然看起来比起上面,我们多写了很多代码,但一个显而易见的好处就是我们分离了具体的对象类,所有的创建过程都交给抽象工厂类来负责。
{
return fac -> CreateProduct();
}
ProductAFactory facA;
Product * pA = Create( & facA);
ProductBFactory facB;
Product * pB = Create( & facB);
再来说我们上面那个换肤的例子,有了抽象工厂,我们所要做的就是
1. 继承一个工厂,创建新皮肤的所有对象
2. 把这个工厂穿给换肤的函数
抽象工厂的缺点也比较容易看到,如果要增加一个新的对象,需要在抽象工厂的接口中增加一个CreateXXX的新的方法来支持新对象的创建,这就需要更改所有的工厂子类,有一种比较好的方法是,对每种对象定义一个ID,用如下方法创建,相信大家也看到了,这种方法有一个很大的限制条件就是,所有的对象都要有相同的基类,并且保证强制转换的正确性
#define ID_PRODECT_2 20
class Factory
{
virtual void Product * Create(unsigned int id)
{
switch (id)
{
case ID_PRODECT_1: return new Product1;
case ID_PRODECT_2: return new Product2;
}
}
}
在实现中,有一种情况比较特殊,就是只有一个工厂来负责创建,不需要继承新的工厂类,这样的话,可要把工厂定义成一个singleton的对象,来访问,singleton也是设计模式的一种,以后会提到,不过相信很多人也知道了,因为这是比较常用的一种设计模式
最后,贴一张抽象工厂的UML图,方便大家理解