我的编程空间,编程开发者的网络收藏夹
学习永远不晚

C++工厂方法之对象创建型模式详解

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

C++工厂方法之对象创建型模式详解

1.代码示例

工厂方法模式,简称工厂模式或者多态工厂模式。与简单工厂模式相比,引入了更多的新类,灵活性更强,实现也更加复杂。符合开闭原则,付出的代价是需要新增加多个新的工厂类。

如下,M_UndeadFactoryM_ElementFactoryM_MechanicFactory 类有一个共同的父类 M_ParFactory(工厂抽象类)。

M_ParFactory 类中的 createMonster 成员函数其实就是个工厂方法,工厂方法模式的名字也是由此而来。

#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 M_ParFactory
{
public:
	virtual Monster* createMonster() = 0; // 具体实现在子类中进行
	virtual ~M_ParFactory() {} // 父类的析构函数应该为虚函数
};
// M_Undead怪物类型的工厂,生产M_Undead类型怪物
class M_UndeadFactory : public M_ParFactory
{
public:
	virtual Monster* createMonster()
	{
		Monster *ptmp = new M_Undead(300, 50, 80); // 创建亡灵类怪物
		//这里可以增加一些其他业务代码
		return ptmp;
	}
};
// M_Element怪物类型的工厂,生产M_Element类型怪物
class M_ElementFactory : public M_ParFactory
{
public:
	virtual Monster* createMonster()
	{
		return new M_Element(200, 80, 100); // 创建元素类怪物
	}
};
// M_Mechanic怪物类型的工厂,生产M_Mechanic类型怪物
class M_MechanicFactory : public M_ParFactory
{
public:
	virtual Monster* createMonster()
	{
		return new M_Mechanic(400, 0, 110); // 创建机械类怪物
	}
};
// 全局函数:用于创建怪物对象
// 注意:形参的类型是工厂父类类型的指针,返回类型是怪物父类类型的指针
Monster* Gbl_CreateMonster(M_ParFactory* factory)
{
	return factory->createMonster();
	// createMonster虚函数扮演了多态new的行为,factory指向的具体怪物工厂类不同,创建的怪物对象也不同
}
int main()
{
	M_ParFactory* p_ud_fy = new M_UndeadFactory(); // 多态工厂,注意指针类型
	Monster* pM1 = Gbl_CreateMonster(p_ud_fy); // 产生了一只亡灵类怪物,也是多态,注意返回类型
	// 当然,这里也可以直接写成 Monster *pM1 = p_ud_fy->createMonster();
	M_ParFactory* p_elm_fy = new M_ElementFactory();
	Monster *pM2 = Gbl_CreateMonster(p_elm_fy); // 产生了一只元素类怪物
	M_ParFactory* p_mec_fy = new M_MechanicFactory();
	Monster* pM3 = Gbl_CreateMonster(p_mec_fy); // 产生了一只机械类怪物
	// 释放工厂
	delete p_ud_fy;
	delete p_elm_fy;
	delete p_mec_fy;
	// 释放怪物
	delete pM1;
	delete pM2;
	delete pM3;
	return 0;
}

简单工厂模式把创建对象这件事放到了一个统一的地方来处理,弹性比较差。而工厂方法模式相当于建立了一个程序实现框架,从而让子类来决定对象如何创建。

工厂方法模式往往需要创建一个与产品等级结构(层次)相同的工厂等级结构,这也增加了新类的层次结构和数目。

如果不想创建太多工厂类,又想封装变化,则可以创建怪物工厂子类模板。

#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 M_ParFactory
{
public:
	virtual Monster* createMonster() = 0; // 具体实现在子类中进行
	virtual ~M_ParFactory() {} // 父类的析构函数应该为虚函数
};
template <typename T>
class M_ChildFactory :public M_ParFactory
{
public:
	virtual Monster* createMonster()
	{
		return new T(300, 50, 80); //如果需要不同的值则可以通过createMonster的形参将值传递进来
	}
};
int main()
{
	M_ChildFactory<M_Undead> myFactory;
	Monster* pM10 = myFactory.createMonster();
	// 释放资源
	delete pM10;
	getchar();
	return 0;
}

UML 如下:

在这里插入图片描述

2.工厂方法模式的定义(实现意图)

定义一个用于创建对象的接口(M_ParFactory类中的createMonster成员函数),由子类(M_UndeadFactoryM_ElementFactoryM_MechanicFactory)决定要实例化的类是哪一个。该模式使得某个类(M_UndeadM_ElementM_Mechanic)的实例化延迟到子类(M_UndeadFactoryM_ElementFactoryM_MechanicFactory)。

一般可以认为,将简单工厂模式的代码经过把工厂类进行抽象改造成符合开闭原则后的代码,就变成了工厂方法模式的代码。

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容!  

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

C++工厂方法之对象创建型模式详解

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

java工厂模式创建对象的方法是什么

Java工厂模式创建对象的方法是通过工厂类来创建对象。工厂类根据客户端的需求,创建一种或多种不同类型的对象。这种方法将对象的实例化过程封装到工厂类中,使得客户端只需与工厂类交互,而不需要直接创建对象。工厂模式可以根据需求返回不同类型的对象,
2023-10-20

java设计模式之工厂方法详解

一、概念 工厂方法模式是类的创建模式,又叫虚拟构造子模式(virtual constructor) 或者多态性工厂模式。二、模式动机 定义一个抽像的工厂,将产品的具体创建工作推迟到抽像工厂的具体子类中,有些
2023-05-31

Java工厂模式用法之如何动态选择对象详解

工厂设计模式可能是最常用的设计模式之一,我想大家在自己的项目中都用到过。本文不仅仅是关于工厂模式的基本知识,更是讨论如何在运行时动态选择不同的方法进行执行,你们可以看看是不是和你们项目中用的一样
2023-03-10

C++ 成员函数详解:对象方法的泛型编程与模板化

c++++ 成员函数是类内部定义的函数,可访问类的数据成员和变量。泛型编程和模板化使代码可重用且独立于数据类型。泛型编程允许编写可用于不同数据类型的代码,而模板化允许创建可用于不同类型成员函数的类。对于需要计算不同形状面积的程序,可使用模板
C++ 成员函数详解:对象方法的泛型编程与模板化
2024-04-29

C++ 成员函数详解:对象方法在设计模式中的应用

c++++ 成员函数在设计模式中的应用包括:封装数据、避免重复代码和提高可测试性。实战案例中,工厂模式通过成员函数实现:抽象产品接口定义共同行为,具体产品类实现具体行为,工厂根据类型创建产品,客户使用成员函数创建和使用产品。C++ 成员函数
C++ 成员函数详解:对象方法在设计模式中的应用
2024-04-29

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录