C++11 设计模式4. 抽象工厂(Abstract Factory)模式

问题的提出

从前面我们已经使用了工厂方法模式 解决了一些问题。

现在 策划又提出了新的需求:对于各个怪物,在不同的场景下,怪物的面板数值会发生变化,

    //怪物分类:亡灵类,元素类,机械类
    //战斗场景分类:沼泽地区,山脉地区,城镇。

那么就有9类怪物====>沼泽地亡灵类、元素类、机械类,山脉地区亡灵类、元素类、机械类,城镇中的亡灵类、元素类、机械类
    //工厂方法模式:一个工厂创建一种类怪物。我们就要创建9个工厂了。

抽象模式的核心思想

    //但如果一个工厂子类能够创建不止一种而是多种具有相同规则的怪物对象,那么就可以有效的减少所创建的工厂子类数量,这就是抽象工厂模式的核心思想。
 

两个概念:a)产品等级结构   b)产品族

在这里,我们先要弄清楚 两个概念:a)产品等级结构   b)产品族
    //抽象工厂模式是按照产品族来生产产品(产地相同的用一个工厂来生产)——一个地点有一个工厂,该工厂负责生产本产地的所有产品。
 

代码实现

第一步:肯定是先将9个类先弄出来

第二步:第二步,定义一个抽象工厂类

    //所有工厂类的父类

第三步:具体沼泽地区的工厂

#include <iostream>
using namespace std;namespace _namespace1 {//第一步,定义9个怪物和其父类//怪物父类class Monster{public://构造函数Monster(int life, int magic, int attack) :m_life(life), m_magic(magic), m_attack(attack) {}virtual ~Monster() {} //做父类时析构函数应该为虚函数protected://可能被子类访问的成员,所以用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;}};//如上已经把9个怪物定义出来了//第二步,定义一个抽象工厂类//所有工厂类的父类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(200, 80, 110); //创建沼泽元素类怪物}virtual Monster* createMonster_Mechanic(){return new M_Mechanic_Swamp(400, 0, 90); //创建沼泽机械类怪物}};//--------------------------//山脉地区的工厂class M_Factory_Mountain :public M_ParFactory{public:virtual Monster* createMonster_Undead(){return new M_Undead_Mountain(300, 50, 80); //创建山脉亡灵类怪物}virtual Monster* createMonster_Element(){return new M_Element_Mountain(200, 80, 100); //创建山脉元素类怪物}virtual Monster* createMonster_Mechanic(){return new M_Mechanic_Mountain(600, 0, 110); //创建山脉机械类怪物}};//--------------------------//城镇的工厂class M_Factory_Town :public M_ParFactory{public:virtual Monster* createMonster_Undead(){return new M_Undead_Town(300, 50, 80); //创建城镇亡灵类怪物}virtual Monster* createMonster_Element(){return new M_Element_Town(200, 80, 100); //创建城镇元素类怪物}virtual Monster* createMonster_Mechanic(){return new M_Mechanic_Town(400, 0, 110); //创建城镇机械类怪物}};}int main() {_namespace1::M_ParFactory* p_mou_fy = new _namespace1::M_Factory_Mountain(); //多态工厂,山脉地区的工厂_namespace1::Monster* pM1 = p_mou_fy->createMonster_Element(); //创建山脉地区的元素类怪物_namespace1::M_ParFactory* p_twn_fy = new _namespace1::M_Factory_Town(); //多态工厂,城镇的工厂_namespace1::Monster* pM2 = p_twn_fy->createMonster_Undead(); //创建城镇地区的亡灵类怪物_namespace1::Monster* pM3 = p_twn_fy->createMonster_Mechanic(); //创建城镇地区的机械类怪物//释放资源//释放工厂delete p_mou_fy;delete p_twn_fy;delete pM1;delete pM2;delete pM3;return 0;
}

第二个例子:

不同厂商生产不同部件范例
    //芭比娃娃:身体(包括头、颈部、躯干、四肢)、衣服、鞋子
    //中国,日本,美国 厂商
    //要求:制作两个芭比娃娃,第一个:身体,衣服,鞋子,全部采用中国厂商制造的部件。
                            //第二个:身体采用中国厂商,衣服部件采用日本厂商,鞋子部件采用美国厂商。
    //类的设计思路:
    //a)将身体,衣服,鞋子 这三个部件实现为抽象类。
    //b)实现一个抽象工厂,分别用来生产身体、衣服、鞋子这三个部件。
    //c)针对不同厂商的每个部件实现具体的类以及每个厂商所代表的具体工厂。

namespace _nmsp3
{//身体抽象类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 AbstractFactory{public://所创建的部件应该稳定的保持这三个部件,才适合抽象工厂模式virtual Body* createBody() = 0; //创建身体virtual Clothes* createClothes() = 0; //创建衣服virtual Shoes* createShoes() = 0; //创建鞋子virtual ~AbstractFactory() {}};//---------------------------//芭比娃娃类class BarbieDoll{public://构造函数BarbieDoll(Body* tmpbody, Clothes* tmpclothes, Shoes* tmpshoes){body = tmpbody;clothes = tmpclothes;shoes = tmpshoes;}void Assemble() //组装芭比娃娃{cout << "成功组装了一个芭比娃娃:" << endl;body->getName();clothes->getName();shoes->getName();}private:Body* body;Clothes* clothes;Shoes* shoes;};//---------------------------//中国厂商实现的三个部件class China_Body :public Body{public:virtual void getName(){cout << "中国厂商产的_身体部件" << endl;}};class China_Clothes :public Clothes{public:virtual void getName(){cout << "中国厂商产的_衣服部件" << endl;}};class China_Shoes :public Shoes{public:virtual void getName(){cout << "中国厂商产的_鞋子部件" << endl;}};//创建一个中国工厂class ChinaFactory : public AbstractFactory{public:virtual Body* createBody(){return new China_Body;}virtual Clothes* createClothes(){return new China_Clothes;}virtual Shoes* createShoes(){return new China_Shoes;}};//---------------------------//日本厂商实现的三个部件class Japan_Body :public Body{public:virtual void getName(){cout << "日本厂商产的_身体部件" << endl;}};class Japan_Clothes :public Clothes{public:virtual void getName(){cout << "日本厂商产的_衣服部件" << endl;}};class Japan_Shoes :public Shoes{public:virtual void getName(){cout << "日本厂商产的_鞋子部件" << endl;}};//创建一个日本工厂class JapanFactory : public AbstractFactory{public:virtual Body* createBody(){return new Japan_Body;}virtual Clothes* createClothes(){return new Japan_Clothes;}virtual Shoes* createShoes(){return new Japan_Shoes;}};//---------------------------//美国厂商实现的三个部件class America_Body :public Body{public:virtual void getName(){cout << "美国厂商产的_身体部件" << endl;}};class America_Clothes :public Clothes{public:virtual void getName(){cout << "美国厂商产的_衣服部件" << endl;}};class America_Shoes :public Shoes{public:virtual void getName(){cout << "美国厂商产的_鞋子部件" << endl;}};//创建一个美国工厂class AmericaFactory : public AbstractFactory{public:virtual Body* createBody(){return new America_Body;}virtual Clothes* createClothes(){return new America_Clothes;}virtual Shoes* createShoes(){return new America_Shoes;}};
}int main() {//创建第一个芭比娃娃------------//(1)创建一个中国工厂_nmsp3::AbstractFactory* pChinaFactory = new _nmsp3::ChinaFactory();//(2)创建中国产的各种部件_nmsp3::Body* pChinaBody = pChinaFactory->createBody();_nmsp3::Clothes* pChinaClothes = pChinaFactory->createClothes();_nmsp3::Shoes* pChinaShoes = pChinaFactory->createShoes();//(3)创建芭比娃娃_nmsp3::BarbieDoll* pbd1obj = new _nmsp3::BarbieDoll(pChinaBody, pChinaClothes, pChinaShoes);pbd1obj->Assemble(); //组装芭比娃娃cout << "-------------------------------------" << endl;//创建第二个芭比娃娃------------//(1)创建另外两个工厂:日本工厂,美国工厂_nmsp3::AbstractFactory* pJapanFactory = new _nmsp3::JapanFactory();_nmsp3::AbstractFactory* pAmericaFactory = new _nmsp3::AmericaFactory();//(2)创建中国产的身体部件,日本产的衣服部件,美国产的鞋子部件_nmsp3::Body* pChinaBody2 = pChinaFactory->createBody();_nmsp3::Clothes* pJapanClothes = pJapanFactory->createClothes();_nmsp3::Shoes* pAmericaShoes = pAmericaFactory->createShoes();//(3)创建芭比娃娃_nmsp3::BarbieDoll* pbd2obj = new _nmsp3::BarbieDoll(pChinaBody2, pJapanClothes, pAmericaShoes);pbd2obj->Assemble(); //组装芭比娃娃//最后记得释放内存----------------delete pbd1obj;delete pChinaShoes;delete pChinaClothes;delete pChinaBody;delete pChinaFactory;//------------delete pbd2obj;delete pAmericaShoes;delete pJapanClothes;delete pChinaBody2;delete pAmericaFactory;delete pJapanFactory;return 0;
}

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


    //工厂方法模式和抽象工厂模式区别:
    //a)工厂方法模式:一个工厂生产一个产品
    //b)抽象工厂模式:一个工厂生产多个产品(产品族)

    //抽象工厂模式的定义(实现意图):提供一个接口(AbstractFactory),
           //让该接口负责创建一系列相关或者相互依赖的对象(Body,Clothes,Shoes),而无需指定他们具体的类。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据交换格式】网络socket编程温度采集智能存储与上报项目技术------JSON、TLV

作者简介&#xff1a; 一个平凡而乐于分享的小比特&#xff0c;中南民族大学通信工程专业研究生在读&#xff0c;研究方向无线联邦学习 擅长领域&#xff1a;驱动开发&#xff0c;嵌入式软件开发&#xff0c;BSP开发 作者主页&#xff1a;一个平凡而乐于分享的小比特的个人主页…

蓝桥杯物联网竞赛_STM32L071KBU6_全部工程及国赛省赛真题及代码

包含stm32L071kbu6全部实验工程、源码、原理图、官方提供参考代码及国、省赛真题及代码 链接&#xff1a;https://pan.baidu.com/s/1pXnsMHE0t4RLCeluFhFpAg?pwdq497 提取码&#xff1a;q497

【零基础学数据结构】双向链表

1.双向链表的概念 1.1头节点 1.2带头双向循环链表 注意&#xff1a; 哨兵位创建后&#xff0c;首尾连接自己 1.3双链表的初始化 // 双向链表的初始化 void ListInit(ListNode** pphead) {// 给双链表创建一个哨兵位*pphead ListBuyNode(-1); } 2.双向链表的打印 // 双向…

扭蛋机小程序:线上扭蛋机模式发展空间有多大?

潮玩行业近几年的发展非常快&#xff0c;推动了扭蛋机市场的发展&#xff0c;越来越多的人加入到了扭蛋机赛道中&#xff0c;市场迎来了新的发展期。如今&#xff0c;我国的二次元文化的发展不断成熟&#xff0c;扭蛋机主打的二次元商品迎来了更多的商业机会。 一、互联网扭蛋机…

uniapp 上传视频到阿里云之后回显视频获取视频封面

uniapp 上传视频到阿里云之后回显视频获取视频封面 官网的解决方案 1.initial-time Number 指定视频初始播放位置&#xff0c;单位为秒&#xff08;s&#xff09;。 没什么卵用 2.使用 uni.createVideoContext(“myVideo”, this).seek(number)。 没什么卵用 <video :id&quo…

Proteus 8 的使用记录

创建仿真文件 新建文件&#xff1a;默认下一步&#xff0c;至完成创建。 功能选择如图&#xff1a; 放置器件 常用元器件名称 keywords 常用51单片机 AT89C52 晶振 CRYSTAL 电阻 RES 排阻 RESPACK-8 瓷片电容 CAP 电解电容 CAP-ELEC 单刀单掷开关 S…

【Tars-go】腾讯微服务框架学习使用03-- TarsUp协议

3 TarsUP协议 统一通信协议 TarsTup | TarsDocs (tarscloud.github.io) TarsDocs/base at master TarsCloud/TarsDocs (github.com) &#xff1a; 有关于tars的所有介绍 每一个rpc调用双方都约定一套数据序列化协议&#xff0c;gprc用的是protobuff&#xff0c;tarsgo是统一…

C语言 函数——函数封装与程序的健壮性

目录 函数封装&#xff08;Encapsulation&#xff09; 如何增强程序的健壮性&#xff1f; 如何保证不会传入负数实参&#xff1f; 函数设计的基本原则 函数封装&#xff08;Encapsulation&#xff09; 外界对函数的影响——仅限于入口参数 函数对外界的影响——仅限于一个…

[CSS]使用方式+样式属性

层叠样式表&#xff08;Cascading Style Sheets&#xff09;&#xff0c;与HTML一样&#xff0c;也是一种标记语言&#xff0c;其作用就是给HTML页面标签添加各种样式&#xff0c;定义网页的显示效果&#xff0c;将网页内容和显示样式进行分离&#xff0c;提高了显示功能。简单…

【漏洞复现】WordPress Welcart 任意文件读取漏洞(CVE-2022-4140)

0x01 产品简介 Welcart 是一款免费的 WordPress 电子商务插件。Welcart 具有许多用于制作在线商店的功能和自定义设置。您可以轻松创建自己的原始在线商店。 0x02 漏洞概述 Welcart存在任意文件读取漏洞&#xff0c;未授权的攻击者可以通过该漏洞读取任意文件&#xff0c;获…

2024年MathorCup数学建模A题移动通信网络中PCI规划问题解题文档与程序

2024年第十四届MathorCup高校数学建模挑战赛 A题 移动通信网络中PCI规划问题 原题再现&#xff1a; 物理小区识别码(PCI)规划是移动通信网络中下行链路层上&#xff0c;对各覆盖小区编号进行合理配置&#xff0c;以避免 PCI 冲突、PCI 混淆以及 PCI 模3 千扰等现象。PCI 规划…

时序预测 | Matlab实现SSA-ESN基于麻雀搜索算法(SSA)优化回声状态网络(ESN)的时间序列预测

时序预测 | Matlab实现SSA-ESN基于麻雀搜索算法(SSA)优化回声状态网络(ESN)的时间序列预测 目录 时序预测 | Matlab实现SSA-ESN基于麻雀搜索算法(SSA)优化回声状态网络(ESN)的时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.Matlab实现SSA-ESN基于麻雀搜索…

Unity DOTS1.0 入门(3) System与SystemGroup 概述

System与SystemGroup 概述 System System是提供一种代码逻辑,改变组件的数据状态,从一个状态到另外一个状态System在main thread里面运行, system.Update方法每一帧执行一次(其他线程中运行的就是JobSystem的事情了&#xff09;System是通过一个System Group这个体系来决定它…

IP地址定位技术在各领域的作用

IP地址定位是通过确定IP地址的物理位置来定位一个设备的技术&#xff0c;它在现代社会的多个领域中都有着广泛的应用。以下将详细探讨IP地址定位的应用场景&#xff0c;以期对读者有所启发。 首先&#xff0c;在网络安全领域&#xff0c;IP地址定位发挥着至关重要的作用。网络…

10 Php学习:循环

在 PHP 中&#xff0c;提供了下列循环语句&#xff1a; while - 只要指定的条件成立&#xff0c;则循环执行代码块do…while - 首先执行一次代码块&#xff0c;然后在指定的条件成立时重复这个循环for - 循环执行代码块指定的次数foreach - 根据数组中每个元素来循环代码块 当…

【300套】基于Springboot+Vue的Java实战开发项目(附源码+演示视频+LW)

大家好&#xff01;我是程序员一帆&#xff0c;感谢您阅读本文&#xff0c;欢迎一键三连哦。 &#x1f9e1;今天给大家分享300的Java毕业设计&#xff0c;基于Springbootvue框架&#xff0c;这些项目都经过精心挑选&#xff0c;涵盖了不同的实战主题和用例&#xff0c;可做毕业…

Rocky(Centos)数据库等高并发或高io应用linux系统调优,及硬件问题排查(含网络、磁盘、系统监控)

一、系统参数优化 默认的最大打开文件数是1024.不满足生产环境的要求。按照如下配置&#xff1a; 1、修改 systemctl管理的 servie 资源限制 编辑/etc/systemd/system.conf # 全局的打开文件数 DefaultLimitNOFILE2097152 # 全局打开进程数 DefaultLimitNPROC655352、调整系…

【c++】优先级队列|反向迭代器(vector|list)

优先级队列的常用函数的使用 #include<iostream> #include<queue> using namespace std;int main() {priority_queue<int>st;st.push(1);st.push(7);st.push(5);st.push(2);st.push(3);st.push(9);while (!st.empty()){cout << st.top() << &qu…

2024年MathorCup数学建模B题甲骨文智能识别中原始拓片单字自动分割与识别研究解题文档与程序

2024年第十四届MathorCup高校数学建模挑战赛 B题 甲骨文智能识别中原始拓片单字自动分割与识别研究 原题再现&#xff1a; 甲骨文是我国目前已知的最早成熟的文字系统&#xff0c;它是一种刻在龟甲或兽骨上的古老文字。甲骨文具有极其重要的研究价值&#xff0c;不仅对中国文…

MLeaksFinder报错

1.报错&#xff1a;FBClassStrongLayout.mm 文件&#xff1a;layoutCache[currentClass] ivars; 解决&#xff1a;替换为layoutCache[(id)currentClass] ivars; 2.编译正常但运行时出现crash indirect_symbol_bindings[i] cur->rebinding FBRetainCycleDetector iOS15 …