简单工厂(Simple Factory)

2023-11-03

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

工厂模式可以细分为:简单工厂模式,工厂方法模式,抽象工厂模式。

1.代码示例

#include <iostream>

using namespace std;

// 怪物父类
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 : public Monster
{
public:
	// 构造函数
	M_Undead(int life, int magic, int attack) : Monster(life, magic, attack)
	{
		cout << "一个亡灵类怪物来到了这个世界" << endl;
	}
	// 其他代码略
};

// 元素类怪物
class M_Element : public Monster
{
public:
	// 构造函数
	M_Element(int life, int magic, int attack) : Monster(life, magic, attack)
	{
		cout << "一个元素类怪物来到了这个世界" << endl;
	}
	// 其他代码略
};

// 机械类怪物
class M_Mechanic : public Monster
{
public:
	// 构造函数
	M_Mechanic(int life, int magic, int attack) : Monster(life, magic, attack)
	{
		cout << "一个机械类怪物来到了这个世界" << endl;
	}
	// 其他代码略
};

int main()
{

	Monster* pM1 = new M_Undead(300, 50, 80); // 产生一只亡灵类怪物
	Monster* pM2 = new M_Element(200, 80, 100); // 产生一只元素类怪物
	Monster* pM3 = new M_Mechanic(400, 0, 110); // 产生一只机械类怪物

	// 释放资源
	delete pM1;
	delete pM2;
	delete pM3;
	
	return 0;
}

在上面的代码中,使用 new 具体类名 来创建对象是一种依赖具体类型的紧耦合关系。

简单工厂模式的实现思路:使用工厂类可以实现创建怪物的代码与各个具体怪物类对象要实现的逻辑代码隔离。把依赖范围尽可能缩小,把容易变化的代码段限制在一个小范围内,就可以在很大程度上提高代码的可维护性和可扩展性。

#include <iostream>

using namespace std;

// 怪物父类
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 : public Monster
{
public:
	// 构造函数
	M_Undead(int life, int magic, int attack) : Monster(life, magic, attack)
	{
		cout << "一个亡灵类怪物来到了这个世界" << endl;
	}
	// 其他代码略
};

// 元素类怪物
class M_Element : public Monster
{
public:
	// 构造函数
	M_Element(int life, int magic, int attack) : Monster(life, magic, attack)
	{
		cout << "一个元素类怪物来到了这个世界" << endl;
	}
	// 其他代码略
};

// 机械类怪物
class M_Mechanic : public Monster
{
public:
	// 构造函数
	M_Mechanic(int life, int magic, int attack) : Monster(life, magic, attack)
	{
		cout << "一个机械类怪物来到了这个世界" << endl;
	}
	// 其他代码略
};

// 怪物工厂类
class MonsterFactory
{
public:
	// 简单工厂模式
	Monster* createMonster(string strmontype)
	{
		Monster* prtnobj = nullptr;
		if (strmontype == "udd") // udd代表要创建亡灵类怪物
		{
			prtnobj = new M_Undead(300, 50, 80);
		}
		else if (strmontype == "elm") // elm代表要创建元素类怪物
		{
			prtnobj = new M_Element(200, 80, 100);
		}
		else if (strmontype == "mec") // mec代表要创建机械类怪物
		{
			prtnobj = new M_Mechanic(400, 0, 110);
		}
		return prtnobj;
	}
};

int main()
{
	MonsterFactory facobj;
	Monster* pM1 = facobj.createMonster("udd"); // 创建一只亡灵类怪物,当然,这里必须知道udd代表的是创建亡灵类怪物
	Monster* pM2 = facobj.createMonster("elm"); // 创建一只元素类怪物
	Monster* pM3 = facobj.createMonster("mec"); // 创建一只机械类怪物

	// 释放资源
	delete pM1;
	delete pM2;
	delete pM3;

	return 0;
}

如果用 static 修饰成员函数 createMonster,此时简单工厂模式又可以称为静态工厂方法模式(Static Factory Method)。

#include <iostream>

using namespace std;

// 怪物父类
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 : public Monster
{
public:
	// 构造函数
	M_Undead(int life, int magic, int attack) : Monster(life, magic, attack)
	{
		cout << "一个亡灵类怪物来到了这个世界" << endl;
	}
	// 其他代码略
};

// 元素类怪物
class M_Element : public Monster
{
public:
	// 构造函数
	M_Element(int life, int magic, int attack) : Monster(life, magic, attack)
	{
		cout << "一个元素类怪物来到了这个世界" << endl;
	}
	// 其他代码略
};

// 机械类怪物
class M_Mechanic : public Monster
{
public:
	// 构造函数
	M_Mechanic(int life, int magic, int attack) : Monster(life, magic, attack)
	{
		cout << "一个机械类怪物来到了这个世界" << endl;
	}
	// 其他代码略
};

// 怪物工厂类
class MonsterFactory
{
public:
	// 静态工厂方法模式(Static Factory Method)
	static Monster* createMonster(string strmontype)
	{
		Monster* prtnobj = nullptr;
		if (strmontype == "udd") // udd代表要创建亡灵类怪物
		{
			prtnobj = new M_Undead(300, 50, 80);
		}
		else if (strmontype == "elm") // elm代表要创建元素类怪物
		{
			prtnobj = new M_Element(200, 80, 100);
		}
		else if (strmontype == "mec") // mec代表要创建机械类怪物
		{
			prtnobj = new M_Mechanic(400, 0, 110);
		}
		return prtnobj;
	}
};

int main()
{	

	Monster* pM1 = MonsterFactory::createMonster("udd"); // 创建一只亡灵类怪物,当然,这里必须知道udd代表的是创建亡灵类怪物
	Monster* pM2 = MonsterFactory::createMonster("elm"); // 创建一只元素类怪物
	Monster* pM3 = MonsterFactory::createMonster("mec"); // 创建一只机械类怪物

	// 释放资源
	delete pM1;
	delete pM2;
	delete pM3;

	return 0;
}

如果想要增加新怪物,可以通过增加新的 if-else 分支来实现,但这违背了面向对象程序设计原则中的开闭原则(Open Close Principle, OCP)。

开闭原则,说的是代码扩展性问题,即对扩展开放,对修改关闭(封闭)。

开闭原则的详细解释:当增加新功能,不应该通过修改已经存在的代码来进行,而是应该通过扩展代码(比如增加新类、增加新成员函数)来进行。

如果 if-else 分支不多,则适当违反开闭原则是完全可以接受的。大家要在代码的可读性和可扩展性之间做出权衡。

UML 如下:

在这里插入图片描述

2.简单工厂模式的定义(实现意图)

定义一个工厂类(MonsterFactory),该类的成员函数(createMonster)可以根据不同参数创建并返回不同的类对象,被创建的对象所属的类(M_Undead、M_Element、M_Mechanic)一般都具有相同的父类(Monster)。调用者(这里指main函数)无需关心创建对象的细节。

简单工厂方法模式实现了创建怪物类代码(createMonster)与具体怪物类(M_Undead、M_Element、M_Mechanic)解耦合的效果。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

简单工厂(Simple Factory) 的相关文章

  • 6.9行为型---访问者模式

    在现实生活中 有些集合对象中存在多种不同的元素 且每种元素也存在多种不同的访问者和处理方式 例如 公园中存在多个景点 也存在多个游客 不同的游客对同一个景点的评价可能不同 医院医生开的处方单中包含多种药元素 査看它的划价员和药房工作人员对它
  • 一道经典面试题透彻理解面向对象编程思想和简单工厂模式

    一道经典的面试题如下 用一种面向对象编程语言实现一个计算器来满足整数的加减乘除运算 大部分人的代码如下 1 0版本 include
  • 设计模式(4):工厂模式之简单工厂模式

    目录 一 什么是简单工厂模式 二 代码举例 三 总结 一 什么是简单工厂模式 简单工厂模式是一种创建型设计模式 这个模式实现了工厂设计模式的最基本形态 通过一个工厂类决定创建出哪一种产品类的实例 简单工厂模式由以下几个核心角色组成 工厂类
  • 单件(Singleton):对象创建型模式

    文章目录 1 单件类的基本概念和实现 2 单件类在多线程中可能导致的问题 2 1 粗暴加锁 不推荐 2 2 双重加锁 存在潜在问题 2 3 一个好的解决方法 3 饿汉式与懒汉式 3 1 饿汉式 3 2 懒汉式 4 单件类对象内存释放问题 4
  • Gof23设计模式之简单工厂/静态工厂模式

    在java中 万物皆对象 这些对象都需要创建 如果创建的时候直接new该对象 就会对该对象耦合严重 假如我们要更换对象 所有new对象的地方都需要修改一遍 这显然违背了软件设计的开闭原则 如果我们使用工厂来生产对象 我们就只和工厂打交道就可
  • 3.5设计模式——————接口隔离原则——面向对象设计原则

    接口隔离原则的定义 接口隔离原则 Interface Segregation Principle ISP 要求程序员尽量将臃肿庞大的接口拆分成更小的和更具体的接口 让接口中只包含客户感兴趣的方法 2002 年罗伯特 C 马丁给 接口隔离原则
  • 工厂模式(分简单工厂模式、工厂方法模式、抽象工厂模式)

    1 工厂模式概述 1 1 简单工厂模式 简单工厂模式是一种创建型设计模式 它实现了创建对象的功能 但不使用任何具体类的名称 客户端通过调用工厂类的静态方法来创建一个具体的对象 无需关心对象创建的细节 1 2 工厂方法模式 工厂方法模式是一种
  • 面试之设计模式(简单工厂模式)

    案例 在面试时 面试官让你通过面对对象语言 用Java实现计算器控制台程序 要求输入两个数和运算符号 得出结果 大家可能想到是如下 public static void main String args Scanner scanner ne
  • C++ 大话设计之《简单工厂模式》(优缺点,设计原理,常用场景)

    简单工厂是一种创建型模式 优点 简单工厂模式能够提高生产效率和生产力 缺点 简单工厂模式将所有产品的创建逻辑集中在一个工厂类中 一旦这个工厂类出现问题 整个系统都会受到影响 如果要添加新的产品类 需要修改工厂类的代码 违反了开闭原则 对扩展
  • 5.4结构型模式—————装饰模式

    装饰模式的定义与特点 装饰 Decorator 模式的定义 指在不改变现有对象结构的情况下 动态地给该对象增加一些职责 即增加其额外功能 的模式 它属于对象结构型模式 装饰 Decorator 模式的主要优点有 采用装饰模式扩展对象的功能比
  • 简单工厂模式(静态工厂方法模式)

    概述 简单工厂模式专门定义一个类来负责创建其他类的实例 被创建的实例通常都具有共同的父类 不是23种模式中的一种 是一种编码习惯 优点 1 工厂类含有必要的判断逻辑 可以决定在什么时候创建哪一个产品类的实例 客户端可以免除直接创建产品对象的
  • 5.0结构型模式—概述

    结构型模式描述如何将类或对象按某种布局组成更大的结构 它分为类结构型模式和对象结构型模式 前者采用继承机制来组织接口和类 后者釆用组合或聚合来组合对象 由于组合关系或聚合关系比继承关系耦合度低 满足 合成复用原则 所以对象结构型模式比类结构
  • JavaScript设计模式(二)——简单工厂模式、抽象工厂模式、建造者模式

    个人简介 个人主页 前端杂货铺 学习方向 主攻前端方向 正逐渐往全干发展 个人状态 研发工程师 现效力于中国工业软件事业 人生格言 积跬步至千里 积小流成江海 推荐学习 前端面试宝典 Vue2 Vue3 Vue2 3项目实战 Node js
  • 1.软件设计模式概述

    软件设计模式的产生背景 设计模式 这个术语最初并不是出现在软件设计中 而是被用于建筑领域的设计中 1977 年 美国著名建筑大师 加利福尼亚大学伯克利分校环境结构中心主任克里斯托夫 亚历山大 Christopher Alexander 在他
  • 3.6设计模式————迪米特法则——面向对象设计原则

    迪米特法则的定义 迪米特法则 Law of Demeter LoD 又叫作最少知识原则 Least Knowledge Principle LKP 产生于 1987 年美国东北大学 Northeastern University 的一个名为
  • 5.1结构型模式————代理模式

    在有些情况下 一个客户不能或者不想直接访问另一个对象 这时需要找一个中介帮忙完成某项任务 这个中介就是代理对象 例如 购买火车票不一定要去火车站买 可以通过 12306 网站或者去火车票代售点买 又如找女朋友 找保姆 找工作等都可以通过找中
  • 4.5创建型模式—————建造者模式(Bulider模式)

    在软件开发过程中有时需要创建一个复杂的对象 这个复杂对象通常由多个子部件按一定的步骤组合而成 例如 计算机是由 OPU 主板 内存 硬盘 显卡 机箱 显示器 键盘 鼠标等部件组装而成的 采购员不可能自己去组装计算机 而是将计算机的配置要求告
  • 模板方法(Template Method):类行为型模式

    文章目录 1 设计模式 Design Pattern 1 1 概述 1 2 分类 2 模板方法 Template Method 类行为型模式 2 1 代码示例 2 2 模板方法模式的定义 实现意图 1 设计模式 Design Pattern
  • 三十、纯虚函数、抽象类、多态、简单工厂模式

    一 纯虚函数 虚函数是多态是实现多态的前提 如果我们需要在基类中定义共同的结构 那么接口就需要定义成虚函数 但是很多情况下基类的接口是无法实现的 比如形状类Shape 定义一个Draw方法 很明显这个方法没法实现 因为我们可以画出圆 正方形
  • 设计模式——简单工厂模式

    简单工厂模式定义为 简单工厂模式又称为静态工厂方法模型 它属于类创建型模式 在简单工厂模式中 可以根据参数的不同返回不同类的实例 简单工厂专门定义一个类来负责创建其他类的实例 被创建的实例通常都具有共同的父类 简单工厂模式结构图 简单工厂模

随机推荐

  • Go入门教程

    什么是Go语言 Go 又称 Golang 是 Google 的 Robert Griesemer Rob Pike 及 Ken Thompson 开发的一种静态强类型 编译型语言 Go 语言语法与 C 相近 但功能上有 内存安全 GC 垃圾
  • 102263 - ArabellaCPC 2019(部分)解题报告

    link A Is It Easy easy include
  • 使用随机森林回归填补缺失值

    文章目录 一 概述 二 实现 1 导入需要的库 2 加载数据集 3 构造缺失值 4 使用0和均值填充缺失值 5 使用随机森林填充缺失值 6 对填充好的数据进行建模 7 评估效果对比 一 概述 现实中收集的数据 几乎不可能是完美无缺的 往往都
  • 合并两个有序数组(给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 中,使得 num1 成为一个有序数组。)

    void merge int nums1 int nums1Size int m int nums2 int nums2Size int n 定义 让数组从后往前遍历 int i m 1 int j n 1 int len m n 1 如果
  • Python中安装Beautiful Soup成功后出现No module named 'bs4'

    此篇文章主要用来解决在终端中完成了beautiful soup的成功安装 但是在IDLE中依然出现以下错误 gt gt gt from bs4 import BeautifulSoup Traceback most recent call
  • 我的大学职业规划(大一时的思考)

    我的大学职业规划 文章目录 我的大学职业规划 1 计算机科学与技术专业的发展方向 不仅限于计科 2 大学四年应该做什么 3 学校竞赛与证书考核 4 编程学习的境界 以C 举例 5 考研与就业 考公与参军的抉择 写作时间 2021 5 28
  • 学会这八个技术,你离BAT大厂不远了

    红人榜第七期来咯 本期干货 HTTP 本周最受关注的技术关键词TOP8 往下看吧 在如今这个时间和知识都是碎片化的时代 C站根据C1 C4认证的成长路径 进行知识细化整理 形成系统化的知识图谱 小编根据C1认证的成长路径整理了100篇HTT
  • Linux下Gitee的user和email配置,查看配置信息命令

    Linux下Gitee的user和email配置 查看配置信息命令 查看配置信息 git config l 配置邮箱 git config global user email email 配置用户名 git config global us
  • STM32CUBEMX配置教程(二)时钟等内部参数配置

    STM32CUBEMX配置教程 二 时钟等内部参数配置 基于STM32H743VI 使用STM32CUBEMX两年了 始终觉得这个工具非常的方便 但因为不是经常使用 导致有些要点总是会有些遗忘 因此写下这一系列教程以供记忆 顺便让我这个大萌
  • Python 打造最强表白程序(源码)

    此程序结合数据抓取 微信自动发消息 定时任务 实现一个能每天自动定时给你心爱的 ta 发送 你们相识相恋天数 情话 我爱你的图片 具体的消息如下 每天发送的消息格式如下 message 亲爱的 早上好 今天是你和 Koc 相恋的第 天 今天
  • C++性能测试工具——gperftools的安装

    一 软件安装说明 gperftools的安装有两种方式 一种是源码方式 一种是直接安装模式 这里使用源码安装模式 原因是使用直接安装模式比较简单 安装此软件需要先安装libunwind这个软件 所以这里需要通过源码方式安装libunwind
  • 【机器学习】支持向量机【上】硬间隔

    有任何的书写错误 排版错误 概念错误等 希望大家包含指正 在阅读本篇之前建议先学习 机器学习 拉格朗日对偶性 机器学习 核函数 由于字数限制 分成两篇博客 机器学习 支持向量机 上 硬间隔 机器学习 支持向量机 下 软间隔与核函数 支持向量
  • CSS布局flex布局 对齐 等分 均分 详解

    一切都始于这样一个问题 怎样通过 CSS 简单而优雅的实现水平 垂直同时居中 记得刚开始学习 CSS 的时候 看到float属性不由得感觉眼前一亮 顺理成章的联想到 Word 文档排版中用到的的左对齐 右对齐和居中对齐 然而很快就失望的发现
  • 【leetcode】1143.最长公共子序列

    leetcode 1143 最长公共子序列 题目 思路 代码 复杂度 题目 leetcode原题链接 给定两个字符串 text1 和 text2 返回这两个字符串的最长 公共子序列 的长度 如果不存在 公共子序列 返回 0 一个字符串的 子
  • 如何快速查看并定位网页元素代码

    如何快速查看并定位网页元素代码 目的 可以迅速得找出一个网页中对应元素的html代码 1 首先我们打开一个网页 比如 百度首页 2 打开后我们会看到很多的文字链接以及按钮链接 那么我们找到我们想要查看的元素的文字或者按钮 3 我们这里以 百
  • @Cacheable注解属性介绍

    本文目录 1 value cacheNames 属性 2 key属性 3 keyGenerator 属性 4 cacheManager 属性 5 cacheResolver 属性 6 condition 属性 7 unless 属性 8 s
  • C++导出EXCEL开源库xlslib库使用心得

    使用教程 第一步 下载xlslib库 本文建立在xlslib2 5 0版本基础上 下载地址xlsLib download SourceForge net 第二步 切换到解压文件目录xlslib build msvc2008 打开项目xlsl
  • linux查询jvm运行内存使用情况,在Linux下获取正在运行的JVM的总使用内存

    您可以运行 ps aux grep java 这将显示包含在其推出的字符串java的每个应用程序的内存使用情况 这应该是大多数 如果不是所有的Java应用程序 从我的服务器的输出如下 servername servername ps aux
  • 超过飞飞系列-ZYNQ之FPGA学习2.1Verilog语法

    一 VHDL Verilog C语言区别 VHDL 硬件描述语言 美军开发 相对难 不直观 需要专业培训 欧洲发展较好 Verilog 硬件描述语言 设计群体广泛 资源成熟 中国多采用 并行处理运行 C 软件语言 经过C的单片机程序需取码
  • 简单工厂(Simple Factory)

    文章目录 1 代码示例 2 简单工厂模式的定义 实现意图 工厂模式 通过把创建对象的代码包装起来 做到创建对象的代码与具体的业务逻辑代码相隔离的目的 工厂模式可以细分为 简单工厂模式 工厂方法模式 抽象工厂模式 1 代码示例 include