设计模式 -- 抽象工厂模式 AbstractFactory

来源:互联网 发布:洪金宝成龙知乎 编辑:程序博客网 时间:2024/05/14 19:35

抽象工厂模式:算是三大工厂模式中最难理解的一个了,上次校招笔试考过,但是稀里糊涂写成了简单工厂了T_T

首先看一个问题场景:

问题场景:系统里有三个组件a、b、c同时使用,但是a的同类a1、a2和a有相通的地方但是互斥,b和c也一样。一个例子就是windows和linux都有图形窗口Text和Button对象,分别是winText、winButton和linuxText、linuxButton,而winText和winButton必须在系统windows下使用,但是winButton和linuxButton又有共同点,按下后会出发事件等等。

解决方案:抽象工厂模式

       如何选用winButton或者winText,由具体工厂类winFactory负责,有选择合适的产品对象的逻辑,与应用系统的商业逻辑相关

       抽象工厂类负责定义接口,是整个抽象工厂的核心,IFactory

       winButton和linuxButton是一种产品族,有共同的特点,特点由抽象产品类接口定义Button,具体的实现由具体的产品类负责

在抽象工厂模式中,有一个产品族的概念:所谓的产品族,是指位于不同产品等级结构中功能相关联的产品组成的家族。抽象工厂模式所提供的一系列产品就组成一个产品族;而工厂方法提供的一系列产品称为一个等级结构。例如这里的Button和Text就是两个不同的产品族。

抽象工厂模式的使用场景定义非常简单:一个对象族(或是一组没有任何关系的对象)都有相同的约束,则可以使用抽象工厂模式


看结构图:


来一段例子程序:

#include <iostream>#include <memory>using namespace std;//抽象工厂模式 -- 创建不同风格的对话框:windows or Mac//抽象产品:IButtonclass IButton {public:    virtual void draw() = 0;};//具体产品:WindowsButtonclass WindowsButton : public IButton {public:    void draw() { cout << "draw Windows Button" << endl; }};//具体产品:MacButtonclass MacButton : public IButton {public:    void draw() { cout << "draw Mac Button" << endl; }};//抽象产品:ITextBoxclass ITextBox {public:    virtual void draw() = 0;};//具体产品:WindowsButtonclass WindowsTextBox : public ITextBox {public:    void draw() { cout << "draw Windows TextBox" << endl; }};//具体产品:MacButtonclass MacTextBox : public ITextBox {public:    void draw() { cout << "draw Mac TextBox" << endl; }};//抽象工厂:IFactoryclass IFactory {public:    virtual shared_ptr<IButton> createButton() = 0;    virtual shared_ptr<ITextBox> createTextBox() = 0;};//具体的工厂:WindowsFactoryclass WindowsFactory : public IFactory {public:    shared_ptr<IButton> createButton() { return shared_ptr<IButton>(new WindowsButton()); }    shared_ptr<ITextBox> createTextBox() { return shared_ptr<ITextBox>(new WindowsTextBox()); }};//具体的工厂:MacFactoryclass MacFactory : public IFactory {public:    shared_ptr<IButton> createButton() { return shared_ptr<IButton>(new MacButton()); }    shared_ptr<ITextBox> createTextBox() { return shared_ptr<ITextBox>(new MacTextBox());}};int main(){    shared_ptr<IFactory> pIFactory(new MacFactory());    shared_ptr<IButton> pButton(pIFactory->createButton());    shared_ptr<ITextBox> pTextBox(pIFactory->createTextBox());    pButton->draw();  //draw Mac Button    pTextBox->draw();  //draw Mac TextBox    return 0;}

注意:以上代码引用了C++11的shared_ptr,所以编译时候注意编译器有无启用C++最新标准。

另外,大话设计模式中的一个例子非常好

系统基于不同的数据库产品,访问数据,结构图如下:



最后和工厂方法比较下:

抽象工厂模式:
多个抽象产品类,每个抽象产品类可以派生出多个具体产品类。   
一个抽象工厂类,可以派生出多个具体工厂类。   
每个具体工厂类可以创建多个具体产品类的实例。   
    
和工厂方法区别:
工厂方法模式只有一个抽象产品类,而抽象工厂模式有多个。   
工厂方法模式的具体工厂类只能创建一个具体产品类的实例,而抽象工厂模式可以创建多个。