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

设计模式介绍

一、抽象工厂

1. 抽象工厂定义

提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类

2. 抽象工厂本质

抽象工厂模式的本质:选择产品簇的实现

3. 抽象工厂结构和说明

(1) 结构

在这里插入图片描述
在这里插入图片描述

(2) 调用顺序

在这里插入图片描述

4. 抽象工厂适用情况

  • 如果希望一个系统独立于它的产品的创建、组合和表示的时候。换句话说,希望一个系统只是知道产品的接口,而不关心实现的时候。
  • 如果一个系统要由多个产品系列中的一个来配置的时候。换句话说,就是可以动态地切换产品簇的时候。
  • 如果要强调一系列相关产品的接口,以便联合使用它们的时候。

5. 抽象工厂优缺点

(1) 优点
  • 分离接口和实现
    客户端使用抽象工厂来创建需要的对象,而客户端根本就不知道具体的实现是谁,客户端只是面向产品的接口编程而已。也就是说,客户端从具体的产品实现中解耦
  • 使得切换产品簇变得容易
    因为一个具体的工厂实现代表的是一个产品簇,比如上面例子的 Schemel代表装机方案一: Intel的CPU+技嘉的主板,如果要切换成为 Scheme2,那就变成了装机方案二:AMD的CPU+微星的主板。
    客户端选用不同的工厂实现,就相当于是在切换不同的产品簇
(2) 缺点
  • 不太容易扩展新的产品
    前面也提到这个问题了,如果需要给整个产品簇添加一个新的产品,那么就需要修改抽象工厂,这样就会导致修改所有的工厂实现类。在下面示例中提供了一个可以扩展工厂的方式来解决这个问题,但是又不够安全。如何选择,则要根据实际应用来权衡。
  • 容易造成类层次复杂
    在使用抽象工厂模式的时候,如果需要选择的层次过多,那么会造成整个类层次变得复杂。
    举个例子来说,就比如下面提到的DAO的示例,现在这个DAO只有一个选择的层次,也就是选择是使用关系型数据库来实现,还是用Xml来实现。现在考虑这样一种情况,如果关系型数据库实现里面又分成几种,比如,基于 Oracle的实现、基于 Sqlserver的实现、基于 Mysql的实现等。那么客户端怎么选择呢?不会把所有可能的实现情况全部都做到一个层次上吧,这个时候客户端就需要一层一层地选择,也就是整个抽象工厂的实现也需要分出层次来,每一层负责一种选择,也就是一层屏蔽一种变化,这样很容易造成复杂的类层次结构。
    在这里插入图片描述

6. 相关模式

  • 抽象工厂模式和工厂方法模式
    这两个模式既有区别,又有联系,可以组合使用。
    工厂方法模式一般是针对单独的产品对象的创建,而抽象工厂模式注重产品簇对象的创建,这是它们的区别。
    如果把抽象工厂创建的产品簇简化,这个产品簇就只有一个产品,那么这个时候的抽象工厂跟工厂方法是差不多的,也就是抽象工厂可以退化成工厂方法,而工厂方法又可以退化成简单工厂,这也是它们的联系。
    在抽象工厂的实现中,还可以使用工厂方法来提供抽象工厂的具体实现,也就是说它们可以组合使用。
  • 抽象工厂模式和单例模式
    这两个模式可以组合使用。
    在抽象工厂模式里面,具体的工厂实现,在整个应用中,通常一个产品系列只需要一个实例就可以了,因此可以把具体的工厂实现成为单例。

二、抽象工厂示例代码

//普通抽象工厂代码
#include <iostream>
using namespace std;

//抽象产品A
class AbstractProductA {
public:
    virtual ~AbstractProductA(){}
    virtual void Operation() = 0;
};

//具体产品A1
class ProductA1 : public AbstractProductA {
public:
    void Operation() {
        cout << "ProductA1" << endl;
    }
};

//具体产品A2
class ProductA2 : public AbstractProductA {
public:
    void Operation() {
        cout << "ProductA2" << endl;
    }
};

//抽象产品B
class AbstractProductB {
public:
    virtual ~AbstractProductB(){}
    virtual void Operation() = 0;
};

//具体产品B1
class ProductB1 : public AbstractProductB {
public:
    void Operation() {
        cout << "ProductB1" << endl;
    }
};

//具体产品B2
class ProductB2 : public AbstractProductB {
public:
    void Operation() {
        cout << "ProductB2" << endl;
    }
};

//抽象工厂
class AbstractFactory {
public:
    virtual AbstractProductA* CreateProductA() = 0;
    virtual AbstractProductB* CreateProductB() = 0;
    virtual ~AbstractFactory(){}
};

//具体工厂1:生产产品A1和B1
class ConcreteFactory1 : public AbstractFactory {
public:
    ProductA1* CreateProductA() {
        return new ProductA1();
    }
    ProductB1* CreateProductB() {
        return new ProductB1();
    }
};

//具体工厂2:生产产品A2和B2
class ConcreteFactory2 : public AbstractFactory {
public:
    ProductA2* CreateProductA() {
        return new ProductA2();
    }
    ProductB2* CreateProductB() {
        return new ProductB2();
    }
};

int main() {
    //示例代码就不判空了
    AbstractFactory* af1 = new ConcreteFactory1();
    // 具体工厂创建对应的具体产品
    AbstractProductA* apa1 = af1->CreateProductA();  // 工厂1创建产品A
    AbstractProductB* apb1 = af1->CreateProductB();  // 工厂1创建产品B
    apa1->Operation();  // ProductA1
    apb1->Operation();  // ProductB1

    AbstractFactory* af2 = new ConcreteFactory2();
    AbstractProductA* apa2 = af2->CreateProductA();  // 工厂2创建产品A
    AbstractProductB* apb2 = af2->CreateProductB();  // 工厂2创建产品B
    apa2->Operation();  // ProductA2
    apb2->Operation();  // ProductB2

    delete apa1;
    delete apa2;
    delete af1;
    delete apb1;
    delete apb2;
    delete af2;
    return 0;
}
//参数化抽象工厂代码
//这里用于扩展产品系列, 比如之前已经有了产品A和B,现在要在增加一个产品C
#include <iostream>
using namespace std;

//抽象产品
class AbstractProduct {
public:
    virtual ~AbstractProduct(){}
    virtual void Operation() = 0;
};

//抽象产品A
class AbstractProductA : public AbstractProduct  {
public:
    virtual ~AbstractProductA(){}
    virtual void Operation() = 0;
};

//具体产品A1
class ProductA1 : public AbstractProductA {
public:
    void Operation() {
        cout << "ProductA1" << endl;
    }
};

//具体产品A2
class ProductA2 : public AbstractProductA {
public:
    void Operation() {
        cout << "ProductA2" << endl;
    }
};

//抽象产品B
class AbstractProductB : public AbstractProduct {
public:
    virtual ~AbstractProductB(){}
    virtual void Operation() = 0;
};

//具体产品B1
class ProductB1 : public AbstractProductB {
public:
    void Operation() {
        cout << "ProductB1" << endl;
    }
};

//具体产品B2
class ProductB2 : public AbstractProductB {
public:
    void Operation() {
        cout << "ProductB2" << endl;
    }
};

//新增抽象产品C
class AbstractProductC : public AbstractProduct{
public:
    virtual ~AbstractProductC(){}
    virtual void Operation() = 0;
};

//新增具体产品C1
class ProductC1 : public AbstractProductC {
public:
    void Operation() {
        cout << "ProductC1" << endl;
    }
};

//抽象工厂
class AbstractFactory {
public:
    virtual AbstractProduct* CreateProduct(int type) = 0;
    virtual ~AbstractFactory(){}
};

//具体工厂1:生产产品A1和B1
class ConcreteFactory1 : public AbstractFactory {
public:
    AbstractProduct * CreateProduct(int type) {
        if(type == 1) //创建A
        {
            return new ProductA1();
        }else if(type == 2) //创建B
        {
            return new ProductB1();
        }
        return nullptr;
    }
};

//具体工厂2:生产产品A2和B2
class ConcreteFactory2 : public AbstractFactory {
public:
    AbstractProduct * CreateProduct(int type) {
        if(type == 1) //创建A
        {
            return new ProductA2();
        }else if(type == 2) //创建B
        {
            return new ProductB2();
        }
        return nullptr;
    }
};

//新增具体工厂3:生产产品A1和B1 和新增生产C1
class ConcreteFactory3 : public AbstractFactory {
public:
    AbstractProduct * CreateProduct(int type) {
        if(type == 1) //创建A
        {
            return new ProductA2();
        }else if(type == 2) //创建B
        {
            return new ProductB2();
        }else if(type == 3) //创建C
        {
            return new ProductC1();
        }
        return nullptr;
    }
};

int main() {
    //示例代码就不判空了 和 释放 资源了
    AbstractFactory* af1 = new ConcreteFactory1();
    // 具体工厂创建对应的具体产品
    AbstractProduct* apa1 = af1->CreateProduct(1);  // 工厂1创建产品A
    AbstractProduct* apb1 = af1->CreateProduct(2);  // 工厂1创建产品B
    AbstractProduct* apc1 = af1->CreateProduct(3);  // 工厂1创建产品C
    apa1->Operation();  // ProductA1
    apb1->Operation();  // ProductB1
    if(apc1)
    {
        apc1->Operation();
    }

    AbstractFactory* af2 = new ConcreteFactory2();
    AbstractProduct* apa2 = af2->CreateProduct(1);  // 工厂2创建产品A
    AbstractProduct* apb2 = af2->CreateProduct(2);  // 工厂2创建产品B
    AbstractProduct* apc2 = af2->CreateProduct(3);  // 工厂2创建产品C
    apa2->Operation();  // ProductA2
    apb2->Operation();  // ProductB2
    if(apc2)
    {
        apc2->Operation();
    }

    AbstractFactory* af3 = new ConcreteFactory3();
    AbstractProduct* apa3 = af3->CreateProduct(1);  // 工厂3创建产品A
    AbstractProduct* apb3 = af3->CreateProduct(2);  // 工厂3创建产品B
    AbstractProduct* apc3 = af3->CreateProduct(3);  // 工厂3创建产品C
    apa3->Operation();  // ProductA2
    apb3->Operation();  // ProductB2
    if(apc3)
    {
        apc3->Operation();
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值