【C++基础】简单工程模式、工厂模式、抽象工程模式

news2025/2/24 3:02:15

本文参考:简单工厂模式 - 人造恶魔果实工厂1 | 爱编程的大丙​​​​​​ ​​​​​​工厂模式 - 人造恶魔果实工厂2 | 爱编程的大丙​​​​​

​​​​​抽象工厂模式 - 弗兰奇一家 | 爱编程的大丙

工厂我们就可以得到想要的东西,在程序设计中,这种模式就叫做工厂模式,工厂生成出的产品就是某个类的实例,也就是对象。关于工厂模式一共有三种,分别是:简单工厂模式、工厂模式、抽象工厂模式。

不论使用哪种工厂模式其主要目的都是实现类与类之间的解耦合,这样我们在创建对象的时候就变成了拿来主义,使程序更加便于维护。

简单工厂模式

基于简单工厂模式去创建对象的时候,需要提供一个工厂类,专门用于生产需要的对象,这样关于对象的创建操作就被剥离出去了。

简单工厂模式相关类的创建和使用步骤:

1、创建一个新的类, 可以将这个类称之为工厂类。对于简单工厂模式来说,需要的工厂类只有一个。
2、在这个工厂类中添加一个公共的成员函数,通过这个函数来创建我们需要的对象,关于这个函数一般将其称之为工厂函数。
3、关于使用,首先创建一个工厂类对象,然后通过这个对象调用工厂函数,这样就可以生产出一个指定类型的实例对象了。

下面以生成三种“动物型恶魔果实”为例 

#include <iostream>
using namespace std;

class AbstractSmile
{
public:
    virtual void transform() {}
    virtual void ability() {}
    virtual ~AbstractSmile() {}
};
// 人造恶魔果实· 绵羊形态
class SheepSmile : public AbstractSmile
{
public:
    void transform() override
    {
        cout << "变成人兽 -- 山羊人形态..." << endl;
    }
    void ability() override
    {
        cout << "将手臂变成绵羊角的招式 -- 巨羊角" << endl;
    }
};

// 人造恶魔果实· 狮子形态
class LionSmile : public AbstractSmile
{
public:
    void transform() override
    {
        cout << "变成人兽 -- 狮子人形态..." << endl;
    }
    void ability() override
    {
        cout << "火遁· 豪火球之术..." << endl;
    }
};

class BatSmile : public AbstractSmile
{
public:
    void transform() override
    {
        cout << "变成人兽 -- 蝙蝠人形态..." << endl;
    }
    void ability() override
    {
        cout << "声纳引箭之万剑归宗..." << endl;
    }
};

// 恶魔果实工厂类
enum class Type:char{SHEEP, LION, BAT};
class SmileFactory
{
public:
    SmileFactory() {}
    ~SmileFactory() {}
    AbstractSmile* createSmile(Type type)
    {
        AbstractSmile* ptr = nullptr;
        switch (type)
        {
        case Type::SHEEP:
            ptr = new SheepSmile;
            break;
        case Type::LION:
            ptr = new LionSmile;
            break;
        case Type::BAT:
            ptr = new BatSmile;
            break;
        default:
            break;
        }
        return ptr;
    }
};

int main()
{
    SmileFactory* factory = new SmileFactory;
    AbstractSmile* obj = factory->createSmile(Type::BAT);
    obj->transform();
    obj->ability();
    return 0;
}

 程序结果:

变成人兽 -- 蝙蝠人形态...
声纳引箭之万剑归宗...

通过上面的代码,实现了一个简单工厂模式

由于人造恶魔果实类有继承关系, 并且实现了多态,所以父类的析构函数也应该是虚函数,这样才能够通过父类指针或引用析构子类的对象。

工厂函数createSmile(Type type)的返回值修改成了AbstractSmile*类型,这是人造恶魔果实类的基类,通过这个指针保存的是子类对象的地址,这样就实现了多态,所以在main()函数中,通过obj对象调用的实际是子类BatSmile中的函数。

工厂模式

简单工厂模式存在一个弊端,其违法了开放-封闭原则。

开放-封闭原则:软件实体(类、模块、函数等)可以扩展,但是不可以修改。也就是说对于扩展是开放的,对于修改是封闭的。

在上面的工厂函数中需要生成三种人造恶魔果实,现在如果想要生成更多,那么就需要在工厂函数的switch语句中添加更多的case,很明显这违背了封闭原则,也就意味着需要基于开放原则来解决这个问题。

所以有了工厂模式。简单工厂模式只有一个工厂类,工厂模式有很多个工厂类

1、一个基类,包含一个虚工厂函数,用于实现多态。
2、多个子类,重写父类的工厂函数。每个子工厂类负责生产一种恶魔果实,这相当于再次解耦,将工厂类的职责再次拆分、细化,如果要生产新品种的恶魔果实,那么只需要添加对应的工厂类,无需修改原有的代码。

完整代码:

#include <iostream>
using namespace std;

class AbstractSmile
{
public:
    virtual void transform() = 0;
    virtual void ability() = 0;
    virtual ~AbstractSmile() {}
};
// 人造恶魔果实· 绵羊形态
class SheepSmile : public AbstractSmile
{
public:
    void transform() override
    {
        cout << "变成人兽 -- 山羊人形态..." << endl;
    }
    void ability() override
    {
        cout << "将手臂变成绵羊角的招式 -- 巨羊角" << endl;
    }
};

// 人造恶魔果实· 狮子形态
class LionSmile : public AbstractSmile
{
public:
    void transform() override
    {
        cout << "变成人兽 -- 狮子人形态..." << endl;
    }
    void ability() override
    {
        cout << "火遁· 豪火球之术..." << endl;
    }
};

class BatSmile : public AbstractSmile
{
public:
    void transform() override
    {
        cout << "变成人兽 -- 蝙蝠人形态..." << endl;
    }
    void ability() override
    {
        cout << "声纳引箭之万剑归宗..." << endl;
    }
};

// 恶魔果实工厂类
class AbstractFactory
{
public:
    virtual AbstractSmile* createSmile() = 0;
    virtual ~AbstractFactory() {}
};

class SheepFactory : public AbstractFactory
{
public:
    AbstractSmile* createSmile() override
    {
        return new SheepSmile;
    }
    ~SheepFactory()
    {
        cout << "释放 SheepFactory 类相关的内存资源" << endl;
    }
};

class LionFactory : public AbstractFactory
{
public:
    // 工厂函数
    AbstractSmile* createSmile() override
    {
        return new LionSmile;
    }
    ~LionFactory()
    {
        cout << "释放 LionFactory 类相关的内存资源" << endl;
    }

};

class BatFactory : public AbstractFactory
{
public:
    // 工厂函数
    AbstractSmile* createSmile() override
    {
        return new BatSmile;
    }
    ~BatFactory()
    {
        cout << "释放 BatFactory 类相关的内存资源" << endl;
    }
};

int main()
{
    AbstractFactory* factory = new BatFactory;
    AbstractSmile* obj = factory->createSmile();
    obj->transform();
    obj->ability();
    return 0;
}

 抽象工厂模式

 工厂模式创建的产品对象相对简单,抽象工厂模式创建的产品对象相对复杂,这个类组件中有可变的因素,这里以造船为例。

基础型标准型旗舰型
船体木头钢铁合成金属
动力手动内燃机核能
武器速射炮激光

在这个图中有四个抽象类,分别是:

ShipBody 类:船体的抽象类
        有三个子类,在子类中通过不同的材料来建造船体
Weapon 类:武器的抽象类
        有三个子类,在子类中给战船提供不同种类的武器
Engine 类:动力系统抽象类
        有三个子类,在子类中给战船提供不同动力系统


AbstractFactory 类:抽象工厂类
        在子工厂类中生产不同型号的战船
        和ShipBody 、Weapon、Engine有依赖关系,在工厂函数中创建了它们的实例对象
        和Ship 类有依赖关系,在工厂函数中创建了它的实例对象

关于Ship类它可以和ShipBody 、Weapon、Engine可以是聚合关系,也可以是组合关系:
        组合关系:析构Ship类对象的时候,也释放了ShipBody 、Weapon、Engine对象
        聚合关系:析构Ship类对象的时候,没有释放ShipBody 、Weapon、Engine对象

ShipBody类以及其子类:

// 船体
class ShipBody
{
public:
    virtual string getShipBody() = 0;
    virtual ~ShipBody() {}
};

class WoodBody : public ShipBody
{
public:
    string getShipBody() override
    {
        return string("用<木材>制作轮船船体...");
    }
};

class IronBody : public ShipBody
{
public:
    string getShipBody() override
    {
        return string("用<钢铁>制作轮船船体...");
    }
};

class MetalBody : public ShipBody
{
public:
    string getShipBody() override
    {
        return string("用<合金>制作轮船船体...");
    }
};

Engine类以及其子类

// 动力
class Engine
{
public:
    virtual string getEngine() = 0;
    virtual ~Engine() {}
};

class Human : public Engine
{
public:
    string getEngine() override
    {
        return string("使用<人力驱动>...");
    }
};

class Diesel : public Engine
{
public:
    string getEngine() override
    {
        return string("使用<内燃机驱动>...");
    }
};

class Nuclear : public Engine
{
public:
    string getEngine() override
    {
        return string("使用<核能驱动>...");
    }
};

Weapon类以及其子类

// 武器
class Weapon
{
public:
    virtual string getWeapon() = 0;
    virtual ~Weapon() {}
};

class Gun : public Weapon
{
public:
    string getWeapon() override
    {
        return string("配备的武器是<枪>");
    }
};

class Cannon : public Weapon
{
public:
    string getWeapon() override
    {
        return string("配备的武器是<自动机关炮>");
    }
};

class Laser : public Weapon
{
public:
    string getWeapon() override
    {
        return string("配备的武器是<激光>");
    }
};

Ship类

// 轮船类
class Ship
{
public:
    Ship(ShipBody* body, Weapon* weapon, Engine* engine) :
        m_body(body), m_weapon(weapon), m_engine(engine) 
    {
    }
    string getProperty()
    {
        string info = m_body->getShipBody() + m_weapon->getWeapon() + m_engine->getEngine();
        return info;
    }
    ~Ship() 
    {
        delete m_body;
        delete m_engine;
        delete m_weapon;
    }
private:
    ShipBody* m_body = nullptr;
    Weapon* m_weapon = nullptr;
    Engine* m_engine = nullptr;
};

工厂类及其子类 

// 工厂类
class AbstractFactory
{
public:
    virtual Ship* createShip() = 0;
    virtual ~AbstractFactory() {}
};

class BasicFactory : public AbstractFactory
{
public:
    Ship* createShip() override
    {
        Ship* ship = new Ship(new WoodBody, new Gun, new Human);
        cout << "<基础型>战船生产完毕, 可以下水啦..." << endl;
        return ship;
    }
};

class StandardFactory : public AbstractFactory
{
public:
    Ship* createShip() override
    {
        Ship* ship = new Ship(new IronBody, new Cannon, new Diesel);
        cout << "<标准型>战船生产完毕, 可以下水啦..." << endl;
        return ship;
    }
};

class UltimateFactory : public AbstractFactory
{
public:
    Ship* createShip() override
    {
        Ship* ship = new Ship(new MetalBody, new Laser, new Nuclear);
        cout << "<旗舰型>战船生产完毕, 可以下水啦..." << endl;
        return ship;
    }
};

int main()
{
    AbstractFactory* factroy = new StandardFactory;
    Ship* ship = factroy->createShip();
    cout << ship->getProperty();
    delete ship;
    delete factroy;
    return 0;
}

抽象工厂模式适用于比较复杂的多变的业务场景,总体上就是给一系列功能相同但是属性会发生变化的组件(如:船体材料、武器系统、动力系统)添加一个抽象类,这样就可以非常方便地进行后续的拓展,再搭配工厂类就可以创建出我们需要的对象了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1003420.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Nacos使用和注册部分源码介绍

Nacos简单介绍 Nacos致力于帮助您发现、配置和管理微服务。Nacos提供了一组简单易用的特性集&#xff0c;帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos帮助您更敏捷和容易地构建、交付和管理微服务平台。Nacos是构建以“服务”为中心的现代应用架构 (例…

社群团购对接,【概率思维】可以增加你做项目的成功率!

社群团购对接&#xff0c;【概率思维】可以增加你做项目的成功率&#xff01; 今天来聊一个关于概率的问题&#xff0c;我们不管去做社群团购项目、做流量&#xff0c;还是做销售&#xff0c;我们都要有概率思维&#xff0c;有了这个思维以后&#xff0c;就可以增加你的成功率…

input输入框从右边开始输入,光标靠左移动

未设置前 光标在左边 <input type"number" placeholder"请输入分润数量" placeholder-class"shareprofit_placeholder_num" v-model"money">设置后 光标在右边 <input type"number" placeholder"请输入分润数…

C#开发的OpenRA游戏之调试菜单1

C#开发的OpenRA游戏之调试菜单1 在开发一个游戏里,经常需要提供一些调试设置,以便快速地达到需要测试的阶段,否则按正常游戏的进程,就会需要比较久的时间,这样浪费开发人员的时间。 在OpenRA提供一个调试菜单,它就是在下面的界面里: 这个菜单叫做 Debug Menu,当玩家点…

关于游戏开发,还有这些信息你可能不知道

游戏开发是一个复杂而令人兴奋的领域&#xff0c;有许多人不知道的有趣事实和趋势。以下是一些可能令你感兴趣的游戏开发领域的事实&#xff1a; 游戏开发是巨大的产业&#xff1a; 游戏产业已经成为世界上最大的娱乐产业之一&#xff0c;超过电影和音乐产业。这包括移动游戏、…

综合续航达1040公里:腾势计划2024年在香港上市,售价60-100 万

腾势汽车表示&#xff0c;他们计划于2024年在香港地区上市全新的D9车型。这款中大型高端新能源MPV是通过DM-i超级混动技术打造的&#xff0c;由于综合续航能力达到1040公里&#xff0c;且纯电续航最大可达190公里&#xff0c;这款车已经引起了广泛关注。据腾势销售事业部总经理…

华为云云耀云服务器L实例评测|教你如何使用云服务器L实例

目录 一、为什么选择华为云云耀云服务器L实例1、智能不卡顿2、价优随心用3、上手更简单4、管理特省心 二、服务器快速上手1、注册账号2、查看华为云耀云服务器L实例产品信息3、购买4、查看服务器详情5、远程登录6、通过第三方终端连接 三、宝塔面板管理服务器 本篇文章给大家分…

分享一个宝贝,如果你对新奇世界感兴趣,这个绝对不能错过

昨晚没怎么睡好&#xff0c;迷迷糊糊到天亮&#xff0c;6点多起床后反思&#xff0c;应该是因为今天周一&#xff0c;要上班&#xff0c;所以晚上没睡好&#xff0c;好像这叫“周一综合症”&#xff0c;即不想上班。 周末两天其实也没做啥&#xff0c;翻完小说《动物农场》&…

「AIGC」智能美学,AI绘画 API 激发无限创意

引言 随着人工智能&#xff08;AI&#xff09;技术的迅猛发展&#xff0c;AI绘画 API 正在以惊人的速度改变艺术创作的面貌。它不仅为艺术家和创作者提供了全新的创作工具&#xff0c;还激发了无限的创意和想象力。在这个智能美学的时代&#xff0c;让我们一起探索 AI 绘画 AP…

Three.js-矩形块shader

自定义shader代码在文末 调用方式&#xff1a; new AudioMaterial({ row: 10,column: 5,start: new Color("#00CC99"),end: new Color("#d3039c"),brightness: "(p.y < fft && p.y > fft -0.1)" })就是这样 这样 默认不传递fre…

Neo4j安装教程及版本匹配

Neo4j简介 Neo4j是基于java的图形数据库&#xff08;即环境中需预先安装jdk&#xff0c;jdk8是免费的&#xff0c;但是jdk11及更高的版本是收费的&#xff09;&#xff1b;开源&#xff1b;NoSQL(非关系型数据库) windows环境中neo4j与jdk版本的对应关系 neo4j版本jdk版本3.58…

AUTOSAR-UDS诊断

目录 一.AutoSAR 诊断功能概述 二.UDS 服务分类 诊断报文格式 &#xff08;1&#xff09;带有子服务的请求报文 &#xff08;2&#xff09;不带子服务的请求报文 &#xff08;3&#xff09;含有子服务正响应报文 &#xff08;4&#xff09;不含子服务正响应报文 &#…

无涯教程-JavaScript - PMT函数

描述 PMT功能基于固定的还款额和固定的利率来计算贷款的还款额。 语法 PMT (rate, nper, pv, [fv], [type])争论 Argument描述Required/OptionalRateThe interest rate for the loan.RequiredNperThe total number of payments for the loan.RequiredPv 现在的价值,或一系列…

1462. 课程表 IV

文章目录 Tag题目来源题目解读解题思路方法一&#xff1a;Floyd传递闭包方法二&#xff1a;拓扑排序 思考写在最后 Tag 【拓扑排序】【传递闭包】【并查集】【数组】 题目来源 1462. 课程表 IV 题目解读 给你一个表示课程先决条件的数组 prerequisites&#xff0c;prerequis…

LeetCode:88. 合并两个有序数组

给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。 注意&#xff1a;最终&#xff0c;合并后数组…

【深度学习】实验09 使用Keras完成线性回归

文章目录 使用Keras完成线性回归1. 导入Keras库2. 创建数据集3. 划分数据集4. 构造神经网络模型5. 训练模型6. 测试模型7. 分析模型 附&#xff1a;系列文章 使用Keras完成线性回归 Keras是一款基于Python的深度学习框架&#xff0c;以Tensorflow、Theano和CNTK作为后端&#…

AlwaysOn-关于读写分离的误区(一)

前言 很多人认为AlwaysOn在同步提交模式下数据是实时同步的&#xff0c;也就是说在主副本写入数据后可以在辅助副本立即查询到。因此期望实现一个彻底的读写分离策略&#xff0c;即所有的写语句在主副本上&#xff0c;所有的只读语句分离到辅助副本上。这是一个认知误区&#x…

多要素气象站:推动气象监测进入智能化新时代

一、多要素气象站概述 多要素气象站是一种集成了多种气象监测要素的自动化气象站&#xff0c;可实现对温度、湿度、风速、风向、气压、太阳辐射等多项气象参数的实时监测。相较于传统气象站&#xff0c;多要素气象站体积更小、能耗更低&#xff0c;且具备更高的测量精度和更广…

高精度加法[大整数运算]

这里只有大整数运算,浮点数相对来说很少使用到 前言 如果使用C内置的类型来存储大整数(位数有几万位),是会溢出的,得不到正确的值,即使是long long int类型的范围也只是[-9*10^19,9*10^19](无符号是[0,10^20]),所能存储的最大数字也就20位,所以需要高精度算法,高精度加法具体…

人脸签到系统 pyQT+数据库+深度学习

一、简介 人脸签到系统是一种基于人脸识别技术的自动签到和认证系统。它利用计算机视觉和深度学习算法来检测、识别和验证个体的面部特征&#xff0c;以确定其身份并记录其出现的时间。这个系统通常用于各种场景&#xff0c;包括企业、学校、会议、活动和公共交通等&#xff0c…