C++设计模式——抽象工厂模式

问题描述

之前讲到了C++设计模式——工厂方法模式,我们可能会想到,后期产品会越来越多了,建立的工厂也会越来越多,工厂进行了增长,工厂变的凌乱而难于管理;由于工厂方法模式创建的对象都是继承于Product的,所以工厂方法模式中,每个工厂只能创建单一种类的产品,当需要生产一种全新的产品(不继承自Product)时,发现工厂方法是心有余而力不足。

举个例子来说:一个显示器电路板厂商,旗下的显示器电路板种类有非液晶的和液晶的;这个时候,厂商建造两个工厂,工厂A负责生产非液晶显示器电路板,工厂B负责生产液晶显示器电路板;工厂一直就这样运行着。有一天,总经理发现,直接生产显示器的其余部分也挺挣钱,所以,总经理决定,再建立两个工厂C和D;C负责生产非液晶显示器的其余部件,D负责生产液晶显示器的其余部件。此时,旁边参谋的人就说了,经理,这样做不好,我们可以直接在工厂A中添加一条负责生产非液晶显示器的其余部件的生产线,在工厂B中添加一条生产液晶显示器的其余部件的生产线,这样就可以不用增加厂房,只用将现有厂房进行扩大一下,同时也方便工厂的管理,而且生产非液晶显示器电路板的技术人员对非液晶显示的其余部件的生产具有指导的作用,生产液晶显示器电路板也是同理。总经理发现这是一个不错的主意。

再回到软件开发的过程中来,工厂A和B就是之前所说的C++设计模式——工厂方法模式;总经理再次建立工厂C和D,就是重复C++设计模式——工厂方法模式,只是生产的产品不同罢了。这样做的弊端就如参谋所说的那样,增加了管理成本和人力成本。在面向对象开发的过程中,是很注重对象管理和维护的,对象越多,就越难进行管理和维护;如果工厂数量过多,那么管理和维护的成本将大大增加;虽然生产的是不同的产品,但是可以二者之间是有微妙的关系的,如参谋所说,技术人员的一些技术经验是可以借鉴的,这就相当于同一个类中的不同对象,之间是可以公用某些资源的。那么,增加一条流水线,扩大厂房,当然是最好的主意了。

实际问题已经得到了解决,那么如何使用设计模式模拟这个实际的问题呢?那就是接下来所说的抽象工厂模式。

 

UML类图

现在要讲的抽象工厂模式,就是工厂方法模式的扩展和延伸,但是抽象工厂模式,更有一般性和代表性;它具有工厂方法具有的优点,也增加了解决实际问题的能力。

如图所示,抽象工厂模式,就好比是两个工厂方法模式的叠加。抽象工厂创建的是一系列相关的对象,其中创建的实现其实就是采用的工厂方法模式。在工厂Factory中的每一个方法,就好比是一条生产线,而生产线实际需要生产什么样的产品,这是由Factory1和Factory2去决定的,这样便延迟了具体子类的实例化;同时集中化了生产线的管理,节省了资源的浪费。

 

适用场合

工厂方法模式适用于产品种类结构单一的场合,为一类产品提供创建的接口;而抽象工厂方法适用于产品种类结构多的场合,主要用于创建一组(有多个种类)相关的产品,为它们提供创建的接口;就是当具有多个抽象角色时,抽象工厂便可以派上用场。

 

代码实现

#include <iostream>
using namespace std;

// Product A
class ProductA
{
public:
    virtual void Show() = 0;
};

class ProductA1 : public ProductA
{
public:
    void Show()
    {
        cout<<"I'm ProductA1"<<endl;
    }
};

class ProductA2 : public ProductA
{
public:
    void Show()
    {
        cout<<"I'm ProductA2"<<endl;
    }
};

// Product B
class ProductB
{
public:
    virtual void Show() = 0;
};

class ProductB1 : public ProductB
{
public:
    void Show()
    {
        cout<<"I'm ProductB1"<<endl;
    }
};

class ProductB2 : public ProductB
{
public:
    void Show()
    {
        cout<<"I'm ProductB2"<<endl;
    }
};

// Factory
class Factory
{
public:
    virtual ProductA *CreateProductA() = 0;
    virtual ProductB *CreateProductB() = 0;
};

class Factory1 : public Factory
{
public:
    ProductA *CreateProductA()
    {
        return new ProductA1();
    }

    ProductB *CreateProductB()
    {
        return new ProductB1();
    }
};

class Factory2 : public Factory
{
    ProductA *CreateProductA()
    {
        return new ProductA2();
    }

    ProductB *CreateProductB()
    {
        return new ProductB2();
    }
};

int main(int argc, char *argv[])
{
    Factory *factoryObj1 = new Factory1();
    ProductA *productObjA1 = factoryObj1->CreateProductA();
    ProductB *productObjB1 = factoryObj1->CreateProductB();

    productObjA1->Show();
    productObjB1->Show();

    Factory *factoryObj2 = new Factory2();
    ProductA *productObjA2 = factoryObj2->CreateProductA();
    ProductB *productObjB2 = factoryObj2->CreateProductB();

    productObjA2->Show();
    productObjB2->Show();

    if (factoryObj1 != NULL)
    {
        delete factoryObj1;
        factoryObj1 = NULL;
    }

    if (productObjA1 != NULL)
    {
        delete productObjA1;
        productObjA1= NULL;
    }

    if (productObjB1 != NULL)
    {
        delete productObjB1;
        productObjB1 = NULL;
    }

    if (factoryObj2 != NULL)
    {
        delete factoryObj2;
        factoryObj2 = NULL;
    }

    if (productObjA2 != NULL)
    {
        delete productObjA2;
        productObjA2 = NULL;
    }

    if (productObjB2 != NULL)
    {
        delete productObjB2;
        productObjB2 = NULL;
    }
}

 

  • 25
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
桥接模式和抽象工厂是两个不同的设计模式,但是可以结合使用。下面我来简单介绍一下如何在C++中实现桥接模式和抽象工厂。 首先,我们需要定义桥接模式中的抽象类和实现类。假设我们要实现一个图形库,可以绘制不同类型的图形,包括圆形、矩形和三角形。我们可以定义一个抽象类Shape,表示图形的基本属性和方法: ```cpp class Shape { public: virtual void draw() = 0; virtual ~Shape() {} }; ``` 然后,我们定义三个实现类,分别表示圆形、矩形和三角形: ```cpp class Circle : public Shape { public: void draw() override { cout << "Draw Circle." << endl; } }; class Rectangle : public Shape { public: void draw() override { cout << "Draw Rectangle." << endl; } }; class Triangle : public Shape { public: void draw() override { cout << "Draw Triangle." << endl; } }; ``` 接下来,我们需要实现桥接模式中的桥接类,它将抽象类和实现类进行桥接。假设我们要支持不同的绘制方式,包括OpenGL和DirectX。我们可以定义一个抽象类DrawAPI,表示绘制的基本属性和方法: ```cpp class DrawAPI { public: virtual void draw() = 0; virtual ~DrawAPI() {} }; ``` 然后,我们定义两个实现类,分别表示OpenGL和DirectX的绘制方式: ```cpp class OpenGLAPI : public DrawAPI { public: void draw() override { cout << "Draw using OpenGL." << endl; } }; class DirectXAPI : public DrawAPI { public: void draw() override { cout << "Draw using DirectX." << endl; } }; ``` 最后,我们需要使用抽象工厂来创建图形和绘制方式的组合。我们可以定义一个抽象工厂类AbstractFactory,表示图形和绘制方式的组合: ```cpp class AbstractFactory { public: virtual Shape* createShape() = 0; virtual DrawAPI* createDrawAPI() = 0; virtual ~AbstractFactory() {} }; ``` 然后,我们定义两个具体的工厂类,分别表示OpenGL和DirectX的图形和绘制方式的组合: ```cpp class OpenGLFactory : public AbstractFactory { public: Shape* createShape() override { return new Circle(); } DrawAPI* createDrawAPI() override { return new OpenGLAPI(); } }; class DirectXFactory : public AbstractFactory { public: Shape* createShape() override { return new Rectangle(); } DrawAPI* createDrawAPI() override { return new DirectXAPI(); } }; ``` 最后,我们可以使用这些类来绘制图形。例如,我们可以使用OpenGL和圆形来绘制一个图形: ```cpp AbstractFactory* factory = new OpenGLFactory(); Shape* shape = factory->createShape(); DrawAPI* api = factory->createDrawAPI(); api->draw(); shape->draw(); ``` 输出结果为: ``` Draw using OpenGL. Draw Circle. ``` 这就是桥接模式和抽象工厂在C++中的实现。通过使用桥接模式和抽象工厂,我们可以将抽象类和实现类进行解耦,从而实现更加灵活和可扩展的设计。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值