C++ 深入理解工厂模式

前言:

转载请附上连接,本帖原创请勿照抄。

在工厂模式(创新型模式)中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。工厂模式作为一种创建模式,一般在创建复杂对象时,考虑使用;在创建简单对象时,建议直接new完成一个实例对象的创建。

下面先写示例代码,再继续说具体解释,以及具体的区别。

本文作者原创,未经允许请勿转载,本帖原创请勿照抄。

C++ 深入理解工厂模式目录

1、简单工厂模式

2、工厂方法模式

3、抽象工厂模式


1、简单工厂模式

主要特点是需要在工厂类中做判断,从而创造相应的产品,当增加新产品时,需要修改工厂类。

使用简单工厂模式,我们只需要知道具体的产品型号就可以创建一个产品。

缺点:工厂类集中了所有产品类的创建逻辑,如果产品量较大,会使得工厂类变的非常臃肿。

/*
关键代码:创建过程在工厂类中完成。
*/
​
#include <iostream>
​
using namespace std;
​
//定义产品类型信息
typedef enum
{
    Tank_Type_56,
    Tank_Type_96,
    Tank_Type_Num
}Tank_Type;
​
//抽象产品类
class Tank
{
public:
    virtual const string& type() = 0;
};
​
//具体的产品类
class Tank56 : public Tank
{
public:
    Tank56():Tank(),m_strType("Tank56")
    {
    }
​
    const string& type() override
    {
        cout << m_strType.data() << endl;
        return m_strType;
    }
private:
    string m_strType;
};
​
//具体的产品类
class Tank96 : public Tank
{
public:
    Tank96():Tank(),m_strType("Tank96")
    {
    }
    const string& type() override
    {
        cout << m_strType.data() << endl;
        return m_strType;
    }
​
private:
    string m_strType;
};
​
//工厂类
class TankFactory
{
public:
    //根据产品信息创建具体的产品类实例,返回一个抽象产品类
    Tank* createTank(Tank_Type type)
    {
        switch(type)
        {
        case Tank_Type_56:
            return new Tank56();
        case Tank_Type_96:
            return new Tank96();
        default:
            return nullptr;
        }
    }
};
​
​
int main()
{
    TankFactory* factory = new TankFactory();
    Tank* tank56 = factory->createTank(Tank_Type_56);
    tank56->type();
    Tank* tank96 = factory->createTank(Tank_Type_96);
    tank96->type();
​
    delete tank96;
    tank96 = nullptr;
    delete tank56;
    tank56 = nullptr;
    delete factory;
    factory = nullptr;
​
    return 0;
}

本来想举个例子,但是直接说比较好点:

2、工厂方法模式

定义一个创建对象的接口,其子类去具体现实这个接口以完成具体的创建工作。如果需要增加新的产品类,只需要扩展一个相应的工厂类即可。

缺点:产品类数据较多时,需要实现大量的工厂类,这无疑增加了代码量。

/*
关键代码:创建过程在其子类执行。
*/
​
#include <iostream>
​
using namespace std;
​
//产品抽象类
class Tank
{
public:
    virtual const string& type() = 0;
};
​
//具体的产品类
class Tank56 : public Tank
{
public:
    Tank56():Tank(),m_strType("Tank56")
    {
    }
​
    const string& type() override
    {
        cout << m_strType.data() << endl;
        return m_strType;
    }
private:
    string m_strType;
};
​
//具体的产品类
class Tank96 : public Tank
{
public:
    Tank96():Tank(),m_strType("Tank96")
    {
    }
    const string& type() override
    {
        cout << m_strType.data() << endl;
        return m_strType;
    }
​
private:
    string m_strType;
};
​
//抽象工厂类,提供一个创建接口
class TankFactory
{
public:
    //提供创建产品实例的接口,返回抽象产品类
    virtual Tank* createTank() = 0;
};
​
//具体的创建工厂类,使用抽象工厂类提供的接口,去创建具体的产品实例
class Tank56Factory : public TankFactory
{
public:
    Tank* createTank() override
    {
        return new Tank56();
    }
};
​
//具体的创建工厂类,使用抽象工厂类提供的接口,去创建具体的产品实例
class Tank96Factory : public TankFactory
{
public:
    Tank* createTank() override
    {
        return new Tank96();
    }
};
​
​
int main()
{
    TankFactory* factory56 = new Tank56Factory();
    Tank* tank56 = factory56->createTank();
    tank56->type();

    TankFactory* factory96 = new Tank96Factory();
    Tank* tank96 = factory96->createTank();
    tank96->type();
​
    delete tank96;
    tank96 = nullptr;
    delete factory96;
    factory96 = nullptr;
​
    delete tank56;
    tank56 = nullptr;
    delete factory56;
    factory56 = nullptr;
​
    return 0;
}

这里可以这样理解:工厂模式优化了简单工厂模式的代码结构

举个例子:下列两张图片中

左边是简单比较简单,直接初始化了三个固定的值,每次去工厂的时候需要进行判断来产生对应的产品。

右边是优化过后的,main槽函数内直接new 工厂(这步操作和左边图的区别是什么呢?答案是减少了中间商赚差价)同时也提高了代码质量。(明显看着就比较高大上,比较简单)

3、抽象工厂模式

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

当存在多个产品系列,而客户端只使用一个系列的产品时,可以考虑使用抽象工厂模式。

缺点:当增加一个新系列的产品时,不仅需要现实具体的产品类,还需要增加一个新的创建接口,扩展相对困难。

/*
* 关键代码:在一个工厂里聚合多个同类产品。
* 以下代码以白色衣服和黑色衣服为例,白色衣服为一个产品系列,黑色衣服为一个产品系列。白色上衣搭配白色裤子,   黑色上衣搭配黑色裤字。每个系列的衣服由一个对应的工厂创建,这样一个工厂创建的衣服能保证衣服为同一个系列。
*/
​
//抽象上衣类
class Coat
{
public:
    virtual const string& color() = 0;
};
​
//黑色上衣类
class BlackCoat : public Coat
{
public:
    BlackCoat():Coat(),m_strColor("Black Coat")
    {
    }
​
    const string& color() override
    {
        cout << m_strColor.data() << endl;
        return m_strColor;
    }
private:
    string m_strColor;
};
​
//白色上衣类
class WhiteCoat : public Coat
{
public:
    WhiteCoat():Coat(),m_strColor("White Coat")
    {
    }
    const string& color() override
    {
        cout << m_strColor.data() << endl;
        return m_strColor;
    }
​
private:
    string m_strColor;
};
​
//抽象裤子类
class Pants
{
public:
    virtual const string& color() = 0;
};
​
//黑色裤子类
class BlackPants : public Pants
{
public:
    BlackPants():Pants(),m_strColor("Black Pants")
    {
    }
    const string& color() override
    {
        cout << m_strColor.data() << endl;
        return m_strColor;
    }
​
private:
    string m_strColor;
};
​
//白色裤子类
class WhitePants : public Pants
{
public:
    WhitePants():Pants(),m_strColor("White Pants")
    {
    }
    const string& color() override
    {
        cout << m_strColor.data() << endl;
        return m_strColor;
    }
​
private:
    string m_strColor;
};
​
//抽象工厂类,提供衣服创建接口
class Factory
{
public:
    //上衣创建接口,返回抽象上衣类
    virtual Coat* createCoat() = 0;
    //裤子创建接口,返回抽象裤子类
    virtual Pants* createPants() = 0;
};
​
//创建白色衣服的工厂类,具体实现创建白色上衣和白色裤子的接口
class WhiteFactory : public Factory
{
public:
    Coat* createCoat() override
    {
        return new WhiteCoat();
    }
​
    Pants* createPants() override
    {
        return new WhitePants();
    }
};
​
//创建黑色衣服的工厂类,具体实现创建黑色上衣和白色裤子的接口
class BlackFactory : public Factory
{
    Coat* createCoat() override
    {
        return new BlackCoat();
    }
​
    Pants* createPants() override
    {
        return new BlackPants();
    }
};

//调用
Factory *factory1 = new Factory1();
ProductA *productA1 = factory1->CreateProductA();
ProductB *productB1 = factory1->CreateProductB();
productA1->Show();
productB1->Show();
Factory *factory2 = new Factory2();
ProductA *productA2 = factory2->CreateProductA();
ProductB *productB2 = factory2->CreateProductB();
productA2->Show();
productB2->Show();

这里可以这样理解:抽象工厂模式的本质也是工厂模式,本质思想可以参考简单工厂模式中的解释说明。

那么抽象工厂的意义呢?按照代码实现来看可以通过两句话来概括和解释!

抽象模式到底有什么意义?实现了什么?

举个例子身上穿着有衣服裤子鞋子

如果说工厂模式那么,添加一种工厂和商品,添加一个A衣服(工厂),那么这个就是A人(产品)的衣服。

那么抽象模式呢?这个就将工厂模式更加细化,将工厂分为不同的工厂,有产衣服的、裤子的、鞋子的,生产衣服的只能给缺衣服的穿、裤子只能给却裤子的人穿、鞋子只能给却鞋子的人穿。

为什么说扩展困难呢? 大家看一遍代码或者看下来应该会懂。

工厂模式,扩展需要添加一个工厂和产品。

抽象模式呢,需要一个工厂和某些具体的产品还有对应的接口。

猜你喜欢

转载自blog.csdn.net/qq_37529913/article/details/110481121
今日推荐