• 设计模式:工厂模式


    工厂模式:定义一个用于创建对象的接口,由其子类决定实例化哪一个类。这使得一个类的实例化延迟到其子类。

    建议先了解一下简单工厂,以便于对比工厂模式有什么区别:
    简单工厂模式

    我们自己来看工厂模式的通用类图吧!这样可能会更加明显易懂。

    在这里插入图片描述
    如上图,工厂模式由以下几个类构成:
    抽象产品类
    具体产品类:具体的产品,继承抽象产品类
    抽象工厂类
    具体工厂类:继承抽象工厂类,用于创建具体产品类。因此依赖于具体产品类。

    工厂模式优点:
    相比于简单工厂模式,工厂模式
    1.在添加新的产品时,只需要创建新类,无需对已有的类进行修改。符合开放封闭原则。
    2.也封装了产品对象创建的过程。降低了与客户端的耦合度。
    工厂模式的缺点:
    添加一个新的产品时,需要同时添加工厂类和产品类。(这还好吧Q!Q)

    如果看完上面的理论还是觉得有点抽象,我们举个实际点的例子吧!

    想开发一款SLG战争类型游戏,游戏有4个兵种,自然需要4个兵工厂去生产。于是它们的类关系为:
    抽象兵种
    具体兵种:火箭车,坦克,飞机,特种兵,继承抽象兵种
    抽象兵工厂
    火箭车兵工厂,坦克兵工厂,飞机兵工厂,特种兵兵工厂:继承抽象兵工厂,依赖具体兵种

    请看类图:

    在这里插入图片描述
    这里不解释那么多了,直接看代码吧!

    #include 
    using namespace std;
    //抽象士兵
    class Arm
    {
    public:
        virtual void Attack() = 0;
    };
    //具体工厂
    class RocketVehicle:public Arm
    {
    public:
        virtual void Attack()
        {
            cout << "Attack all" << endl;
        };
    
    };
    
    class Tank :public Arm
    {
    public:
        virtual void Attack()
        {
            cout << "Attack first line" << endl;
        };
    };
    
    class Helicopter :public Arm
    {
    public:
        virtual void Attack()
        {
            cout << "Attack column" << endl;
        };
    };
    
    class Soldier :public Arm
    {
    public:
        virtual void Attack()
        {
            cout << "Attack the first one" << endl;
        };
    };
    //抽象工厂
    class Arsenal
    {
    public:
        Arsenal(string name)
        {
            mName = name;
        }
    private:
        string mName;
    };
    //具体工厂
    class RocketVehicleArsenal :public Arsenal
    {
    public:
        RocketVehicleArsenal(string name)
            :Arsenal(name)
        {
        }
        RocketVehicle* Create()
        {
            return new RocketVehicle;
        }
    };
    
    class TankArsenal :public Arsenal
    {
    public:
        TankArsenal(string name)
            :Arsenal(name)
        {
        }
    
        Tank* Create()
        {
            return new Tank;
        }
    };
    
    class HelicopterArsenal :public Arsenal
    {
    public:
        HelicopterArsenal(string name)
            :Arsenal(name)
        {
        }
    
        Helicopter* Create()
        {
            return new Helicopter;
        }
    };
    
    class SoldierArsenal :public Arsenal
    {
    public:
        SoldierArsenal(string name)
            :Arsenal(name)
        {
        }
    
        Soldier* Create()
        {
            return new Soldier;
        }
    };
    
    
    int main()
    {
        //创建工厂
        RocketVehicleArsenal* RVA = new RocketVehicleArsenal("火箭车兵工厂");
        TankArsenal* TA = new TankArsenal("坦克兵工厂");
        HelicopterArsenal* HA = new HelicopterArsenal("直升机兵工厂");
        SoldierArsenal* SA = new SoldierArsenal("特种兵兵工厂");
    
        //生产兵
        RocketVehicle* RV0 = RVA->Create();
        RocketVehicle* RV1 = RVA->Create();
        RocketVehicle* RV2 = RVA->Create();
        RocketVehicle* RV3 = RVA->Create();
        Tank* T0 = TA->Create();
    
        RV0->Attack();
        RV1->Attack();
        T0->Attack();
    }
    
    • 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

    如果你认真看了上面的代码应该很好理解。没看也没关系,我接下来分析给你看。

    四种兵工厂继承了抽象兵工厂
    四种兵种继承了抽象兵种
    可以通过具体兵工厂实现具体兵种,这是生产具有兵种的过程。

    这就是
    SLG战争类型游戏应用工厂模式的整个逻辑。

  • 相关阅读:
    【c++提高1】单调队列
    vue-cil搭建项目
    关于#sql#的问题:高斯库中查询一个字段所有值中是否包含某个值,有没有简单的函数,不用切割函数的sql语录比较简单的推荐下
    02 powershell服务器远程执行命令
    Compose学习-> Text()
    银行分布式存储基础设施创新实践分享
    基于YOLOv7算法的混凝土结构表面裂缝自主识别
    GPS定位系统,GPSBDpro-远程车辆视频录像回放
    计算机网络自顶向下前一章知识点回顾
    使用del语句删除名称对引用计数的影响
  • 原文地址:https://blog.csdn.net/lovedingning/article/details/126774727