当前位置:   article > 正文

C++设计模式----工厂模式_c++ 工厂模式

c++ 工厂模式


工厂模式介绍

使用new创建堆对象,可以实现多态。

而工厂模式,则是把创建对象的代码包装起来,做到创建对象的代码与具体的业务逻辑代码相隔离的目的。

工厂模式细分为三种:简单工厂模式、工厂方法模式、抽象工厂模式。


简单工厂模式

简单工厂模式具体的应用情景

还是假设你是一名游戏程序员,游戏策划告诉你现在有三种怪物:亡灵类怪物、元素类怪物、机械类怪物,它们和主角一样,都有生命值、魔法值、攻击力三个属性。你该如何设计?
你可以选择一个抽象类Monster为父类,然后三种怪物 M_Undead(亡灵类怪物)、M_Element(元素类怪物)、M_Mechanic(机械类怪物) 继承自父类。

#include <iostream>
using namespace std;

namespace hjl_project
{
    //怪物父类
    class Monster
    {
    public:
        Monster(int life, int magic, int attack)
            : m_life(life), m_magic(magic), m_attack(attack)
        {
        }
        virtual ~Monster() {}

    protected:
        //怪物属性
        int m_life;
        int m_magic;
        int m_attack;
    };
    //亡灵类怪物
    class M_Undead : public Monster
    {
    public:
        M_Undead(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "创建了一个亡灵类怪物" << endl;
        }
        virtual ~M_Undead() {}
    };
    //元素类怪物
    class M_Element : public Monster
    {
    public:
        M_Element(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "创建了一个元素类怪物" << endl;
        }
        virtual ~M_Element() {}
    };
    //机械类怪物
    class M_Mechanic : public Monster
    {
    public:
        M_Mechanic(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "创建了一个机械类怪物" << endl;
        }
        virtual ~M_Mechanic() {}
    };
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

接下来,如果你想实例化出怪物,可以选择直接new创建:
在这里插入图片描述

但是上面这样创建怪物的写法,我们需要依赖具体怪物的类名(不知道类名就创建不出怪物)。后续怪物种类增加,继续采用这种方式实在是太低效且难以维护了。

从上面不难看出来,使用new+具体类名来创建对象是一种依赖具体类型的紧耦合关系。

所以我们可以选择增加一个“怪物工厂类”,来帮助我们来创建怪物。通过这样的方式,即使以后怪物种类增加了,main函数中的代码也可以尽量保持稳定。
因为main函数与各个具体怪物类对象要实现的逻辑代码隔离了,这就是简单工厂模式的实现思路。

  //怪物工厂类,用来生产怪物对象
    class MonsterFactory
    {
    public:
        // monster_type为怪物的种类,
        //当然如果想要指定生命值、魔法值、攻击力,也可以修改参数
        Monster *createMonster(string monster_type)
        {
            Monster *p_monster_obj = nullptr;
            //创建亡灵类怪物
            if (monster_type == "udd")
            {
                p_monster_obj = new M_Undead(300, 50, 80);
            }
            //创建元素类怪物
            else if (monster_type == "ele")
            {
                p_monster_obj = new M_Element(500, 50, 80);
            }
            //创建机械类怪物
            else if (monster_type == "mec")
            {
                p_monster_obj = new M_Mechanic(300, 100, 80);
            }
            return p_monster_obj;
        }
    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

在这里插入图片描述

到此为止,我们与怪物类的依赖就变成了与“怪物工厂类”的依赖,依赖关系缩小了,提高了代码的可维护性和可扩展性。 比如,如果以后我们想给怪物属性增加一个参数“防御力”,如果采用原来new的方式,我们需要把每个new的地方都修改了,而采用工厂模式,只需要修改“怪物工厂类”里面的一个函数即可。

但是这样设计也有一个缺点,那就是如果后续我们想增加一个新的怪物类,比如“异能类怪物”,我们就需要修改“怪物工厂类”中的代码,增加新的else if分支。这违背了六大设计原则之中的 “开闭原则”。当然,如果if else分支不多(没有十几个),违背一下“开闭原则”也没问题。

在这里插入图片描述

简单工厂模式的定义

定义一个工厂类,该类可以根据不同的参数创建并返回不同的类对象,被创建的对象所属的类一般都具有相同的父类。

调用者无需关心对象的具体实现细节。

实现了创建对象的代码(工厂类的createMonster),与具体的类(各种怪物类)解耦合的效果。


工厂方法模式

工厂方法模式是使用频率最高的工厂模式。该模式又被简称为 工厂模式或者多态工厂模式

上面提到简单工厂模式违背了“开闭原则”,而工厂方法模式通过增加 “新的工厂类” 来创建新的怪物类型,而不会修改原来的函数。

工厂方法模式具体的应用情景

还是以上面的怪物类型为例子。
我们需要在不修改原来createMonster函数的情况下,增加新的怪物类,如果按照上面简单工厂模式的设计思路,只有一个工厂类,是不可能做到不修改createMonster函数从而增加新的怪物类创建的。

我们可以给每个怪物类都实现一个工厂类,这些工厂类有一个共同的父类(工厂抽象类),通过每个怪物类的工厂类对象,就可以创建出不同的怪物;
如果后续要增加新的怪物类型,只需要再实现一个对应的工厂类即可,并不会修改原来的工厂类。

#include <iostream>
using namespace std;
namespace hjl_project
{
    //怪物父类
    class Monster
    {
    public:
        Monster(int life, int magic, int attack)
            : m_life(life), m_magic(magic), m_attack(attack)
        {
        }
        virtual ~Monster() {}

    protected:
        //怪物属性
        int m_life;
        int m_magic;
        int m_attack;
    };
    //亡灵类怪物
    class M_Undead : public Monster
    {
    public:
        M_Undead(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "创建了一个亡灵类怪物" << endl;
        }
        virtual ~M_Undead() {}
    };
    //元素类怪物
    class M_Element : public Monster
    {
    public:
        M_Element(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "创建了一个元素类怪物" << endl;
        }
        virtual ~M_Element() {}
    };
    //机械类怪物
    class M_Mechanic : public Monster
    {
    public:
        M_Mechanic(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "创建了一个机械类怪物" << endl;
        }
        virtual ~M_Mechanic() {}
    };
    //工厂父类
    class M_ParFactory
    {
    public:
        virtual Monster *createMonster() = 0;
        virtual ~M_ParFactory() {}
    };
    //亡灵类怪物的生产工厂
    class M_UndeadFactory : public M_ParFactory
    {
    public:
        virtual Monster *createMonster()
        {
            Monster *p_monster_obj = nullptr;

            return new M_Undead(300, 50, 80);
        }
        virtual ~M_UndeadFactory() {}
    };
    //元素类怪物的生产工厂
    class M_ElementFactory : public M_ParFactory
    {
    public:
        virtual Monster *createMonster()
        {
            Monster *p_monster_obj = nullptr;

            return new M_Element(300, 50, 80);
        }
        virtual ~M_ElementFactory() {}
    };
    //机械类怪物的生产工厂
    class M_MechanicFactory : public M_ParFactory
    {
    public:
        virtual Monster *createMonster()
        {
            Monster *p_monster_obj = nullptr;

            return new M_Mechanic(300, 50, 80);
        }
        virtual ~M_MechanicFactory() {}
    };
		
	//如果后续增加新的怪物类,只需要再实现一个该怪物类的工厂类即可

    //全局的用于创建怪物对象的函数,形参的类型是工厂父类类型的指针,
    //返回类型是怪物父类类型的指针
    Monster *Gbl_CreateMonster(M_ParFactory *factory)
    {
        //根据factory类型,创建不同的怪物
        return factory->createMonster();
    }
}

int main()
{

    //先创建一个亡灵怪物的工厂类,然后再通过该工厂类创建亡灵类怪物的对象
    hjl_project::M_ParFactory *p_udd_fy = new hjl_project::M_UndeadFactory();
    hjl_project::Monster *pM1 = hjl_project::Gbl_CreateMonster(p_udd_fy);
	//hjl_project::Monster *pM1 = p_udd_fy->createMonster();
		
    hjl_project::M_ParFactory *p_ele_fy = new hjl_project::M_ElementFactory();
    hjl_project::Monster *pM2 = hjl_project::Gbl_CreateMonster(p_ele_fy);

    hjl_project::M_ParFactory *p_mec_fy = new hjl_project::M_MechanicFactory();
    hjl_project::Monster *pM3 = hjl_project::Gbl_CreateMonster(p_mec_fy);

    delete p_udd_fy, pM1, p_ele_fy, pM2, p_mec_fy, pM3;
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125

增加新类,通过增加扩展而不是修改已有代码的方式来实现创建新类对象,符合“开闭原则”。

在这里插入图片描述

到这里,估计你会发现,我们每实现一个怪物类,就需要实现一个对应的怪物工厂类,有点麻烦,其实我们可以通过模板来优化这一步操作。

	//T代表不同怪物的类型
    template <class T>
    class M_ChildFactory : public M_ParFactory
    {
    public:
        virtual Monster *createMonster()
        {
            return new T(300, 50, 80);
        }
    };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

在这里插入图片描述

工厂方法模式的定义

定义一个用于创建对象的接口(工厂父类),由子类(各种怪物的工厂类)决定要实例化的类(创建的怪物)是哪一个。
工厂方法模式使得某个类的实例化延迟到了子类。

工厂方法模式的好处:

  1. 采用封装的方式,易于修改,如果直接用new的话,后续增加参数(比如增加“防御力”属性)会很麻烦,而采用工厂类,只需要修改成员函数即可。
  2. 创建对象前如果需要一些额外的业务代码,就可以将这些代码增加到具体工厂类的createMonster函数中。
  3. 简单工厂模式把创建对象这件事放到了一个统一的地方来处理(都是通过一个类来完成),可扩展性比较差。工厂方法模式相当于建立了一个程序实现框架,从而让子类来决定对象如何创建对象。

工厂方法模式往往需要创建一个与产品等级结构(层次)相同的工厂等级结构,这也增加了各种类的层次结构和数目。


抽象工厂模式

工厂方法模式具体的应用情景1—战斗场景分类

你还是那名游戏程序员,随着你们游戏的发展,战斗场景也逐渐增多,比如战斗的场景有山脉、沼泽、城镇等。
游戏策划这时候想让你在不同的场景下创建不同的怪物,相同类型的怪物在不同场景下属性各不相同,比如亡灵类怪物在山脉中攻击力就比在城镇中高。
目前的怪物有三种:亡灵类、元素类、机械类。通过排列组合,你发现如果按照不同的场景划分不同的怪物,一共有九种类型。
如果按照工厂方法模式的设计思路,就需要创建九个工厂子类,有点麻烦。
有没有一种方法,能够让一个工厂子类能够创建多种具有相同规则的怪物对象呢?这就是抽象工厂模式的思想。

我们引入两个概念:产品等级结构和产品族。
抽象工厂模式按照产品族来生产产品(产地相同的用一个工厂来生产),即一个地点有一个工厂,该工厂负责生产本地区的所有产品。
在这里插入图片描述

于是,你可以创建一个抽象工厂类,这个抽象类里有三个生产接口,分别可以用来生产三种类型的怪物,后面不同的场景如沼泽、山脉等都可以通过继承这个抽象工厂类,来重写这三个生产接口。这样,就可以生产出九种不同类型的怪物了。

#include <iostream>
using namespace std;
namespace hjl_project
{
    //怪物父类
    class Monster
    {
    public:
        Monster(int life, int magic, int attack)
            : m_life(life), m_magic(magic), m_attack(attack)
        {
        }
        virtual ~Monster() {}

    protected:
        //怪物属性
        int m_life;
        int m_magic;
        int m_attack;
    };
    //-----------------------------沼泽地区的怪物----------------
    //沼泽亡灵类怪物
    class M_Undead_Swamp : public Monster
    {
    public:
        M_Undead_Swamp(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "生产出一个沼泽亡灵类怪物" << endl;
        }
    };
    //沼泽元素类怪物
    class M_Element_Swamp : public Monster
    {
    public:
        M_Element_Swamp(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "生产出一个沼泽元素类怪物" << endl;
        }
    };
    //沼泽机械类怪物
    class M_Mechanic_Swamp : public Monster
    {
    public:
        M_Mechanic_Swamp(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "生产出一个沼泽机械类怪物" << endl;
        }
    };
    //-----------------------------山脉地区的怪物----------------
    //山脉亡灵类怪物
    class M_Undead_Mountain : public Monster
    {
    public:
        M_Undead_Mountain(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "生产出一个山脉亡灵类怪物" << endl;
        }
    };
    //山脉元素类怪物
    class M_Element_Mountain : public Monster
    {
    public:
        M_Element_Mountain(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "生产出一个山脉元素类怪物" << endl;
        }
    };
    //山脉机械类怪物
    class M_Mechanic_Mountain : public Monster
    {
    public:
        M_Mechanic_Mountain(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "生产出一个山脉机械类怪物" << endl;
        }
    };
    //-----------------------------城市地区的怪物----------------
    //城市亡灵类怪物
    class M_Undead_Town : public Monster
    {
    public:
        M_Undead_Town(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "生产出一个城市亡灵类怪物" << endl;
        }
    };
    //城市元素类怪物
    class M_Element_Town : public Monster
    {
    public:
        M_Element_Town(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "生产出一个城市元素类怪物" << endl;
        }
    };
    //城市机械类怪物
    class M_Mechanic_Town : public Monster
    {
    public:
        M_Mechanic_Town(int life, int magic, int attack)
            : Monster(life, magic, attack)
        {
            cout << "生产出一个城市机械类怪物" << endl;
        }
    };

    //-----------------工厂类-----------------
    class M_ParFactory
    {
    public:
        //创建亡灵类怪物
        virtual Monster *createMonster_Undead() = 0;
        //创建元素类怪物
        virtual Monster *createMonster_Element() = 0;
        //创建机械类怪物
        virtual Monster *createMonster_Mechanic() = 0;
        virtual ~M_ParFactory() {}
    };
    //沼泽地区的工厂
    class M_Factory_Swamp : public M_ParFactory
    {
    public:
        //创建亡灵类怪物
        virtual Monster *createMonster_Undead()
        {
            return new M_Undead_Swamp(300, 50, 120);
        }
        //创建元素类怪物
        virtual Monster *createMonster_Element()
        {
            return new M_Element_Swamp(400, 50, 120);
        }
        //创建机械类怪物
        virtual Monster *createMonster_Mechanic()
        {
            return new M_Mechanic_Swamp(300, 150, 120);
        }
    };
    //山脉地区的工厂
    class M_Factory_Mountain : public M_ParFactory
    {
    public:
        //创建亡灵类怪物
        virtual Monster *createMonster_Undead()
        {
            return new M_Undead_Mountain(30, 50, 120);
        }
        //创建元素类怪物
        virtual Monster *createMonster_Element()
        {
            return new M_Element_Mountain(40, 50, 120);
        }
        //创建机械类怪物
        virtual Monster *createMonster_Mechanic()
        {
            return new M_Mechanic_Mountain(30, 150, 120);
        }
    };
    //城市地区的工厂
    class M_Factory_Town : public M_ParFactory
    {
    public:
        //创建亡灵类怪物
        virtual Monster *createMonster_Undead()
        {
            return new M_Undead_Town(30, 500, 120);
        }
        //创建元素类怪物
        virtual Monster *createMonster_Element()
        {
            return new M_Element_Town(40, 500, 120);
        }
        //创建机械类怪物
        virtual Monster *createMonster_Mechanic()
        {
            return new M_Mechanic_Town(30, 1500, 120);
        }
    };
}

int main()
{
    //创建一个山脉地区的工厂,然后创建一个山脉地区的亡灵类怪物
    hjl_project::M_ParFactory *p_mou_fy = new hjl_project::M_Factory_Mountain();
    hjl_project::Monster *pM1 = p_mou_fy->createMonster_Undead();
    //创建一个沼泽地区的工厂,然后创建一个沼泽地区的机械类怪物
    hjl_project::M_ParFactory *p_swa_fy = new hjl_project::M_Factory_Swamp();
    hjl_project::Monster *pM2 = p_swa_fy->createMonster_Mechanic();
    //创建一个沼泽地区的工厂,然后创建一个沼泽地区的元素类怪物
    hjl_project::M_ParFactory *p_tow_fy = new hjl_project::M_Factory_Town();
    hjl_project::Monster *pM3 = p_tow_fy->createMonster_Element();
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201

在这里插入图片描述

工厂方法模式具体的应用情景2—不同厂商生产不同产品

现在有一款玩具娃娃,它的部件有 身体、衣服、鞋子组成;这些部件由三个国家的厂商制作:中国、日本、美国。
你需要制作两个娃娃,第一个娃娃的要求:身体、衣服、鞋子全部采用中国厂商制作。第二个娃娃的要求:身体由中国厂商制作,衣服由日本厂商制作,鞋子由美国厂商制作。

在这里插入图片描述

你可以这样设计:
由于身体、衣服、鞋子三种部件都可以被不同的厂商生产,所以可以设置身体、衣服、鞋子的抽象类,然后继承实现不同厂商生产的子类,比如中国生产的身体类。
实现一个工厂抽象类,其中三个抽象函数来生产三种部件,不同厂商通过继承和多态来实现生产属于自己的三种部件。
最后设置娃娃类,通过传入三种部件的抽象指针,来组装娃娃。

#include <iostream>
using namespace std;
namespace hjl_project2
{
    //身体抽象类
    class Body
    {
    public:
        virtual void getName() = 0;
        virtual ~Body() {}
    };
    //衣服抽象类
    class Clothes
    {
    public:
        virtual void getName() = 0;
        virtual ~Clothes() {}
    };
    //鞋子抽象类
    class Shoes
    {
    public:
        virtual void getName() = 0;
        virtual ~Shoes(){};
    };
    //------------------娃娃类-----------
    class Doll
    {
    public:
        Doll(Body *p_body, Clothes *p_clothes, Shoes *p_shoes)
            : body(p_body), clothes(p_clothes), shoes(p_shoes)
        {
        }
        //组装接口
        void Assemble()
        {
            cout << "组装一个娃娃" << endl;
            body->getName();
            clothes->getName();
            shoes->getName();
        }

    private:
        Body *body;
        Clothes *clothes;
        Shoes *shoes;
    };
    //-------------工厂类------------
    class AbstractFactory
    {
    public:
        //工厂稳定地创建三个部件
        virtual Body *createBody() = 0;
        virtual Clothes *createClothes() = 0;
        virtual Shoes *createShoes() = 0;
        virtual ~AbstractFactory() {}
    };
    //中国厂商实现三个部件
    class China_Body : public Body
    {
    public:
        void getName()
        {
            cout << "中国厂商生产身体部件" << endl;
        }
    };
    class China_Clothes : public Clothes
    {
    public:
        void getName()
        {
            cout << "中国厂商生产衣服部件" << endl;
        }
    };
    class China_Shoes : public Shoes
    {
    public:
        void getName()
        {
            cout << "中国厂商生产鞋子部件" << endl;
        }
    };
    //中国工厂
    class ChinaFactory : public AbstractFactory
    {
    public:
        Body *createBody()
        {
            return new China_Body;
        }
        Clothes *createClothes()
        {
            return new China_Clothes;
        }
        Shoes *createShoes()
        {
            return new China_Shoes;
        }
    };
    //日本厂商实现三个部件
    class Japan_Body : public Body
    {
    public:
        void getName()
        {
            cout << "日本厂商生产身体部件" << endl;
        }
    };
    class Japan_Clothes : public Clothes
    {
    public:
        void getName()
        {
            cout << "日本厂商生产衣服部件" << endl;
        }
    };
    class Japan_Shoes : public Shoes
    {
    public:
        void getName()
        {
            cout << "日本厂商生产鞋子部件" << endl;
        }
    };
    //日本工厂
    class JapanFactory : public AbstractFactory
    {
    public:
        Body *createBody()
        {
            return new Japan_Body;
        }
        Clothes *createClothes()
        {
            return new Japan_Clothes;
        }
        Shoes *createShoes()
        {
            return new Japan_Shoes;
        }
    };
    //美国厂商实现三个部件
    class America_Body : public Body
    {
    public:
        void getName()
        {
            cout << "美国厂商生产身体部件" << endl;
        }
    };
    class America_Clothes : public Clothes
    {
    public:
        void getName()
        {
            cout << "美国厂商生产衣服部件" << endl;
        }
    };
    class America_Shoes : public Shoes
    {
    public:
        void getName()
        {
            cout << "美国厂商生产鞋子部件" << endl;
        }
    };
    //美国工厂
    class AmericaFactory : public AbstractFactory
    {
    public:
        Body *createBody()
        {
            return new America_Body;
        }
        Clothes *createClothes()
        {
            return new America_Clothes;
        }
        Shoes *createShoes()
        {
            return new America_Shoes;
        }
    };

}
int main()
{
    //创建第一个娃娃
    // 1.创建一个中国工厂
    hjl_project2::AbstractFactory *p_china_factory = new hjl_project2::ChinaFactory();
    // 2.创建中国工厂生产的部件
    hjl_project2::Body *p_china_body = p_china_factory->createBody();
    hjl_project2::Clothes *p_china_clothes = p_china_factory->createClothes();
    hjl_project2::Shoes *p_china_shoes = p_china_factory->createShoes();
    // 3.使用部件创建娃娃,然后组装
    hjl_project2::Doll *p_obj1 = new hjl_project2::Doll(p_china_body, p_china_clothes, p_china_shoes);
    p_obj1->Assemble();

    cout << "----------------------------------" << endl;

    //创建第二个娃娃
    // 1.创建另外的日本和美国工厂
    hjl_project2::AbstractFactory *p_japan_factory = new hjl_project2::JapanFactory();
    hjl_project2::AbstractFactory *p_america_factory = new hjl_project2::AmericaFactory();
    // 2.创建生产部件
    hjl_project2::Body *p_china_body2 = p_china_factory->createBody();
    hjl_project2::Clothes *p_japan_clothes = p_japan_factory->createClothes();
    hjl_project2::Shoes *p_america_shoes = p_america_factory->createShoes();
    // 3.使用部件创建娃娃,然后组装
    hjl_project2::Doll *p_obj2 = new hjl_project2::Doll(p_china_body2, p_japan_clothes, p_america_shoes);
    p_obj2->Assemble();

    delete p_china_factory, p_china_body, p_china_clothes, p_china_shoes, p_obj1, p_japan_factory, p_america_factory, p_china_body2, p_japan_clothes, p_america_shoes, p_obj2;
    return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215

在这里插入图片描述

在这里插入图片描述

抽象工厂模式的定义

提供一个接口(抽象工厂类),让该接口负责创建一系列相关或者互相依赖的对象(情景1中的三种怪物抽象类型,情景2中的三种部件抽象类型),而无需指定它们具体的类(三种具体的怪物,亡灵类等,三种部件的具体类型,中国厂商生产的身体类型等)。

抽象工厂模式的优缺点

  1. 增加新的场景,如森林场景,怪物种类不变,则只需要增加一个新的子工厂。符合“开闭原则”。即只增加一个新的产品族,就只需要一个新的工厂子类,这是抽象工厂模式的优点。
  2. 如果增加了新的怪物种类,比如“异能类怪物”,那就需要在工厂父类和子类中都增加响应的接口。不符合“开闭原则”,不太适合抽象工厂模式。即增加新产品等级结构,则需要修改抽象层的代码,这是抽象工厂模式的缺点,应避免在产品等级结构不稳定的情况下使用该模式。

工厂方法模式和抽象工厂模式的区别

工厂方法模式适合于用一个工厂生产一个产品。
抽象工厂模式适合于用一个工厂生产多个产品。


工厂模式总结

  1. 从代码的实现复杂度来看,简单工厂模式最简单,工厂方法模式次之,抽象工厂模式最复杂。如果将简单工厂模式的代码修改得符合“开闭原则”,就变成了工厂方法模式;如果修改工厂方法模式的代码,使得一个工厂支持多个产品的生产,那就成了抽象工厂模式。

  2. 从需要的工厂数量上来看,简单工厂数量最少只有一个,工厂方法模式需要的工厂数量最多,抽象工厂模式能够有效减少工厂方法模式中工厂的数量。

  3. 从实际应用上,如果产品数量很少又不经常修改产品类型,只需要使用简单工厂模式即可;如果产品数量很多或者为了满足“开闭原则”,则可以使用工厂方法模式;如果有很多厂商并且一个厂商生产很多产品,则要使用抽象工厂模式。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/386964
推荐阅读
相关标签
  

闽ICP备14008679号