意图:
提供一个接口,以创建一族相关联的对象,而不用去指定它们的具体类。
结构图:
 
 

 
系统设计中,可能需要用到一系列具有相同风格(比如视觉风格的UI控件:WIN或者MAC风格),如果直接将各风格的元素对象真接编码到代码中:
{
    WinButton* button = new WinButton();
    WinForm* Form = new WinForm();
    ......
}
当需要更改元素风格时,需要将代码中所有出现过对象都一处一处更改,显然,这样的硬编码风格是不足取的。此时,即是抽象工厂模式所发力的时刻:
首先:需要为这些元素,此处即以控件为例,建立一个工厂接口类,提供生产对不同的控件的方法接口,如下:
IAbstractFactory{
   virtual Button* CreateButton(){}
   virtual Form* CreateForm(){}
   //.........
}
将不同风格的控件的生成工作,全部放入IFactory的子类中:
 WinStyleFactory : public IAbstractFactory {
    Button* CreateButton(){return new WinButton();}
    Form* CreateForm(){return new WinForm();}
    //........
 }
 
MacStyleFactory : public IAbstractFactory {
    Button* CreateButton(){return new MacButton();}
    Form* CreateForm(){return new MacForm();} 
    //........
 }
其后在代码使用时:
 {
       //当需要改变控件风格时,只要系统初始化工厂对象时将下面的抽象工厂的具
//子类换成相应风格的抽象工厂对象就可以了。
IAbstractFactory* factory = new WinStyleFactory();
// IAbstractFactory* factory = new MacStyleFactory();
 
Button* button = factory. CreateButton();
Form* form = factory. CreateForm();
    //........
 }
即使以后再需要变动控件风格,只需要将新风格的控件工厂类实现,并修改工厂对象就很方便的完成了系统风格的扩展和变换。
只是在系统变动,需要加入新的控件,在实现起来,需要在所有已有类(包括接口和具体的子类)中增加新控件的CreateXXX方法。不易于实现这种形式的扩展。
 
适用范围:
1、 系统独立于其所需产品(对应上面的控件)的产生,组合和表现方法。
2、 系统需要配置成多族(一族对应WIN风格还是MAC风格)元素中的一种时
3、 相同一族的对象设计来一起使用,需要限制风格的统一
4、 你提供的产品类库,只想显示接口而隐藏实现时。
 
实现要点:
1、 在继承实现具体的工厂类的时候使用单件模式(后续内容);
2、 扩展性:针对上面提及的加入新风格的元素族时的需要重新实现一个新的抽象工厂的子类,一种更灵活方便的方法是,在IAbstractFactory中实现的CreateXXX方法中传递一个参数,用以标示产生哪种风格的元素,这样在扩展时,只要添加一种”case”就可以了,但这样的方法,系统无法在运行时获得具体的子类型,即牺牲了一定程度上的安全性。
参考资料:
   《设计模式----可复用面向对象软件的基础》