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),而无需指定他们具体的类。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Fence同步

在《Android图形显示系统》没有介绍到帧同步的相关概念&#xff0c;这里简单介绍补充一下。 在图形显示系统中&#xff0c;图形缓存GraphicBuffer可以被不同的硬件来访问&#xff0c;如CPU、GPU、HWC都可以对缓存进行读写&#xff0c;如果同时对图形缓存进行操作&#xff0c;有…

26、链表-环形链表II

思路&#xff1a; 这道题就是判断链表中是否有环&#xff0c;首先使用集合肯定可以快速地解决&#xff0c;比如通过一个set集合遍历&#xff0c;如果遍历过程中有节点在set中已经存在那么说明存在环。返回这个节点即可 第二种方式就是通过快慢指针方式寻找环。如何做呢&#xf…

Matlab之过球面一点的平面方程

这篇文章描述2件事情&#xff1a; 1、已知球面上任意点&#xff0c;求过该点、地心、与北极点的平面方程&#xff08;即过该点的经线平面方程&#xff09;&#xff1b; 2、绕过球心的任意轴旋转平面得到新平面的方程 一、已知球面上任意点&#xff0c;求过该点、地心、与北极点…

Python:生成表白爱心动画(程序的优化与打包)

目录 效果预览 功能的实现 优化内容 完整代码 性能分析 效果预览 程序参考于&#xff1a;python 爱心代码-CSDN博客https://blog.csdn.net/weixin_74994771/article/details/137294470?spm1000.2115.3001.6382&utm_mediumdistribute.pc_feed_v2.none-task-blog-hot-1…

力扣 |142. 环形链表 II

用快慢指针的方法 根据推出的表达式&#xff1a;slow和fast相遇的时候&#xff0c;让slow和位于头节点的p同时 向前走&#xff0c;刚好在入环的节点处相遇&#xff01;注意&#xff1a;b和c交界的点不一定是从例如-4这个节点处&#xff0c; 可能是0节点处。因为相遇的点只能是…

【软件设计师】计算机软考下午题试题六,Java设计模式之简单工厂模式。

【软件设计师】计算机软考下午题试题六&#xff0c;Java设计模式之简单工厂模式。 代码如下&#xff1a; //简单工厂模式 public class SimpleFactory {public static void main(String[] args) {Product ProductAFactory.createProduct("A");ProductA.info();Produc…

C++---vector容器

是STL容器中的一种常用的容器&#xff0c;由于其大小(size)可变&#xff0c;常用于数组大小不可知的情况下来替代数组。vector容器与数组十分相似&#xff0c;被称为动态数组。时间复杂度为O&#xff08;1&#xff09;。 数组数据通常存储在栈中&#xff0c;vector数据通常存储…

个人简历主页搭建系列-06:jqcv 简历主题安装

jqcv 介绍 大家好呀&#xff0c;前段时间我在忙毕设的事情&#xff0c;这段时间继续写这个专题。 我们之前网站已经成功搭建起来了对吧&#xff0c;但是这个样式明显和我们的简历需求不符合&#xff0c;难道我们要自己配置 css 文件一点点进行修改吗&#xff1f; 其实并不用…

4月全新热文高科技,套用模板一键生成热文,没脑子拷贝,第二天出盈利

撰写热门文章&#xff0c;如今日头条或微信公众号文章&#xff0c;通常需要多长时间呢&#xff1f;从构思主题、搜集资料&#xff0c;到撰写成文&#xff0c;整个过程至少需要1小时&#xff0c;有时甚至可能需要2小时。 项目 地 址&#xff1a;laoa1.cn/1627.html 现在&…

css animation 动画详细学习

学习 CSS 动画是一个深入且富有创造性的过程&#xff0c;它允许开发者创建出引人入胜且交互性强的网页效果。以下是对 CSS 动画学习的一些总结和要点&#xff1a; 1. 关键帧动画&#xff08;keyframes&#xff09; 使用 keyframes 规则定义动画的整个过程。在 keyframes 中&a…

【PyQt5】环境配置

PyQt5 环境配置 一、前言1.1 PyQt5介绍1.2 PyCharm集成Pyqt5 二、pyqt5安装三、PyQt5-tools工具包安装四、常用工具环境配置4.1、环境变量配置4。2、验证是否安装成功 五、pycharm中设置Qt工具&#xff08;Qt Designer、PyUIC、PyRcc&#xff09;5.1、配置Qt Designer5.2、配置…

【计算机毕业设计】日用百货交易网站——后附源码

&#x1f389;**欢迎来到我的技术世界&#xff01;**&#x1f389; &#x1f4d8; 博主小档案&#xff1a; 一名来自世界500强的资深程序媛&#xff0c;毕业于国内知名985高校。 &#x1f527; 技术专长&#xff1a; 在深度学习任务中展现出卓越的能力&#xff0c;包括但不限于…

QT天气预报

QT-天气预报 1.界面设计 2.开发  2.1 重写鼠标右键退出功能  2.2 重写鼠标左键移动窗口  2.3 QtHttp编程获取天气原始数据    2.3.1 发送HTTP请求    2.3.2 读取数据    2.3.3 处理网络失败请求 2.4 JSON数据    2.4.1 QT生成JSON数据    2.4.2 QT解…

[lesson22]对象的销毁

对象的销毁 对象的销毁 生活中的对象都是被初始化后才上市的 生活中的对象被销毁前会做一些清理工作 一般而言&#xff0c;需要销毁的对象都应该做清理 解决方案 为每个类都提供一个public的free函数对象不在需要时立即调用free函数进行清理 存在的问题 free只是一个普通…

wife_wife-攻防世界

题目 注册发现可以注册管理员,但是好像有条件 抓包试试 没思路了 看看其他师傅的wp&#xff0c;用到 js 原型链污染攻击 Nodejs原型链污染攻击基础知识 | Savants Blog (lxscloud.top) 网站后端是Node.js搭建的 原型链污染 简单来讲&#xff0c;通过 newUser.__proto__ …

使用 HBuilderX自动上传Uniapp 微信小程序代码

HBuilderX内置相关环境&#xff0c;开箱即用&#xff0c;无需配置nodejs。本文只介绍发布微信小程序的步骤。 1.下载和安装 HBuilderX hbuilder首页&#xff1a;https://www.dcloud.io/hbuilderx.html 下载hbuilder编辑器,选择对应的系统,Windows和mac正式版即可,下载后免安…

mysql8.0高可用集群架构实战

MySQL :: MySQL Shell 8.0 :: 7 MySQL InnoDB Cluster 基本概述 InnoDB Cluster是MySQL官方实现高可用读写分离的架构方案,其中包含以下组件 MySQL Group Replication,简称MGR,是MySQL的主从同步高可用方案,包括数据同步及角色选举Mysql Shell 是InnoDB Cluster的管理工具,用…

基于SpringBoot+Vue的健身器材用品网站(源码+文档+部署+讲解)

一.系统概述 随着我国经济的高速发展与人们生活水平的日益提高&#xff0c;人们对生活质量的追求也多种多样。尤其在人们生活节奏不断加快的当下&#xff0c;人们更趋向于足不出户解决各种问题&#xff0c;必录德健身器材用品网展现了其蓬勃生命力和广阔的前景。与此同时&#…

AugmentedReality之路-平面检测(5)

本文介绍通过AR检测水平平面和垂直平面&#xff0c;并将检测到的平面转化为Mesh 1、在首页添加功能入口 在首页添加一个按钮&#xff0c;命名为Start World Track 2、自定义ExecStartAREvent 创建ARSessionConfig并取名为ARSessionConfig_World 自定义ExecStartAREvent&…

2024年你应该防范的11个WordPress安全漏洞问题:由资深程序员撰写

微软创始人比尔盖茨曾说过&#xff0c;“安全对每个人都有同样的影响。在网站安全方面&#xff0c;没有特定的主题、目标或受众。” 但WordPress是互联网上最受欢迎的CMS。它也是被黑客攻击次数最多的。针对WordPress的攻击次数超过了每秒2800次。网络攻击会浪费时间、精力和金…