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

目录
  • 1.代码示例
  • 2.工厂方法模式的定义(实现意图)
  • 总结

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)。

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

总结

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

(0)

相关推荐

  • 举例解析设计模式中的工厂方法模式在C++编程中的运用

    工厂方法模式不同于简单工厂模式的地方在于工厂方法模式把对象的创建过程放到里子类里.这样工厂父对象和产品父对象一样,可以是抽象类或者接口,只定义相应的规范或操作,不涉及具体的创建或实现细节. 其类图如下: 实例代码为: #pragma once class IProduct { public: IProduct(void); virtual ~IProduct(void); }; #pragma once #include "iproduct.h" class IPad : public

  • C++设计模式编程中简单工厂与工厂方法模式的实例对比

    简单工厂模式实例 题目:实现计算器的输入2个数和运算符,得到结果 工程结构: (1)头文件 COperationFactory.h(运算符工厂类) (2)源文件 SimpleFactory.cpp(客户端应用类,主函数所在) (3)运算类 COperation.cpp(运算符基类) COperation.h COperationAdd.h(加法运算符子类,继承于COperation) COperationDiv.h (除法运算符子类,继承于COperation) COperationMul.h

  • C++设计模式之工厂方法模式

    问题描述 之前讲到了C++设计模式--简单工厂模式,由于简单工厂模式的局限性,比如:工厂现在能生产ProductA.ProductB和ProductC三种产品了,此时,需要增加生产ProductD产品:那么,首先是不是需要在产品枚举类型中添加新的产品类型标识,然后,修改Factory类中的switch结构代码.是的,这种对代码的修改,对原有代码的改动量较大,易产生编码上的错误(虽然很简单,如果工程大了,出错也是在所难免的!!!).这种对代码的修改是最原始,最野蛮的修改,本质上不能称之为对代码的扩

  • C++设计模式之工厂方法模式的实现及优缺点

    工厂方法模式是在简单工厂模式的缺点上进行优化的,我们都知道,在简单工厂模式中,要去增加或者减少一个产品的类型,都需要修改工厂中的if-else判断.这样子显然不符合我们代码开发中的开闭原则,拓展起来也是非常麻烦的 工厂方法模式 = 简单工厂模式 + "开闭原则" 定义思想:工厂父类负责定义创建产品对象的公共接口,而工厂子类则负责生成具体的产品对象,这样做的目的就是将产品类的实例化操作延迟到工厂子类中完成,即通过工厂子类来确定究竟应该实例化哪一个具体产品类 优点: 不需要记住具体的类名,

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

    目录 1.代码示例 2.工厂方法模式的定义(实现意图) 总结 1.代码示例 工厂方法模式,简称工厂模式或者多态工厂模式.与简单工厂模式相比,引入了更多的新类,灵活性更强,实现也更加复杂.符合开闭原则,付出的代价是需要新增加多个新的工厂类. 如下,M_UndeadFactory.M_ElementFactory.M_MechanicFactory 类有一个共同的父类 M_ParFactory(工厂抽象类). M_ParFactory 类中的 createMonster 成员函数其实就是个工厂方法,

  • 5种Java经典创建型模式详解

    一.概况 总体来说设计模式分为三大类: (1)创建型模式,共五种:工厂方法模式.抽象工厂模式.单例模式.建造者模式.原型模式. (2)结构型模式,共七种:适配器模式.装饰器模式.代理模式.外观模式.桥接模式.组合模式.享元模式. (3)行为型模式,共十一种:策略模式.模板方法模式.观察者模式.迭代子模式.责任链模式.命令模式.备忘录模式.状态模式.访问者模式.中介者模式.解释器模式. 二.设计模式的六大原则 1.开闭原则(Open Close Principle) 开闭原则就是说对扩展开放,对修

  • java存储以及java对象创建的流程(详解)

    java存储: 1)寄存器:这是最快的存储区,位于处理器的内部.但是寄存器的数量有限,所以寄存器根据需求进行分配.我们不能直接进行操作. 2)堆栈:位于通用RAM中,可以通过堆栈指针从处理器那里获取直接支持.堆栈指针往下移动,则分配新的内存.网上移动,则释放内存.但是 在创建程序的时候必须知道存储在堆栈中的所有项的具体生命周期,以便上下的移动指针.一般存储基本类型和java对象引用. 3)堆:位于通用RAM中,存放所有的java对象,不需要知道具体的生命周期. 4)常量存储:常量值通常直接存放在

  • C#设计模式之行为型模式详解

    这里列举行为型模式·到此23种就列完了···这里是看着菜鸟教程来实现··,他里边列了25种,其中过滤器模式和空对象模式应该不属于所谓的23种模式 责任链模式:为请求创建一个接收者对象的链,对请求的发送者和接收者进行解耦,大部分用于web中吧.. Task中的continuewith和微软的tpl数据流应该是类似这种模式的实现吧 using System; using System.Collections.Generic; using System.Linq; using System.Text;

  • Java设计模式之java原型模式详解

    目录 介绍 角色 Java语言提供的clone()方法 代码演示-克隆羊 结论 深浅拷贝 深浅拷贝探讨 实现深克隆的方式一 : 手动对引用对象进行克隆 实现深克隆的方式一 :序列化 原型模式对单例模式的破坏 优缺点 适用场景 原型模式在Spring中的应用场景 总结 介绍 原型模式(Prototype Pattern):使用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象.原型模式是一种对象创建型模式. 原型模式的工作原理很简单:将一个原型对象传给那个要发动创建的对象,这个要发动创建

  • Java工厂模式之简单工厂,工厂方法,抽象工厂模式详解

    目录 1.简单工厂模式 1.定义 2.代码案例 3.适用场景 4.优缺点 2.工厂方法模式 1.定义 2.代码案例 3.适用场景 4.优缺点 3.抽象工厂模式 1.定义 2.代码案例 3.适用场景 4.优缺点 4.总结 1.简单工厂模式 1.定义 简单工厂模式(Simple Factory Pattern)是指由一个工厂对象决定创建出哪一种产品类的实例.属于创建型模式,但它不属于GOF23种设计模式. 2.代码案例 假设以罐头产品的制造为案例 第一步:定义罐头的顶层接口类ICanned /**

  • 结合 ES6 类编写JavaScript 创建型模式

    目录 前言 什么是设计模式? 创建型设计模式 1. 工厂模式 实例 2. 抽象工厂 实例 3. 构建器模式 实例 4. 原型模式 实例 5. 单例模式 实例 前言 什么是设计模式? 设计模式是软件设计中常见问题的解决方案,这些模式很容易重复使用并且富有表现力. 在软件工程中,设计模式(design pattern)是对软件设计中普遍存在(反复出现)的各种问题,所提出的解决方案.它并不直接用来完成代码的编写,而是描述在各种不同情况下,要怎么解决问题的一种方案.面向对象设计模式通常以类别或对象来描述

  • Java设计模式之工厂方法模式详解

    目录 1.工厂方法是什么 2.如何实现 3.代码实现 4.工厂方法模式的优点 5.拓展 1.工厂方法是什么 众所周知,工厂是生产产品的,并且产品供消费者使用.消费者不必关心产品的生产过程,只需要关心用哪种产品就行. 在Java世界中,工厂方法模式和现实功能类似.工厂即一个工厂类,提供获得对象(产品)的方法(工厂方法).其他类(消费者)需要用到某个对象时,只需调用工厂方法就行,不必new这个对象. 2.如何实现 1)创建产品的抽象类或接口---抽象产品 2)创建具体产品的类---具体产品 3)创建

  • Java创建型模式之建造者模式详解

    目录 一.介绍 二.UML类图 三.具体代码 四.lombok的@Builder注解(拓展) 五.在Spring中的应用 一.介绍 建造者模式(Builder Pattern)属于创建型模式.如果一个对象具有复杂的内部结构或者内部属性本身相互依赖(有顺序要求),甚至对象中的某些属性的创建也有一个很复杂的过程,就可以使用建造者模式 二.UML类图 三.具体代码 业务代码 public class Product { private String part1; private String part

  • 深入理解JavaScript系列(28):设计模式之工厂模式详解

    介绍 与创建型模式类似,工厂模式创建对象(视为工厂里的产品)时无需指定创建对象的具体类. 工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类.该模式使一个类的实例化延迟到了子类.而子类可以重写接口方法以便创建的时候指定自己的对象类型. 这个模式十分有用,尤其是创建对象的流程赋值的时候,比如依赖于很多设置文件等.并且,你会经常在程序里看到工厂方法,用于让子类类定义需要创建的对象类型. 正文 下面这个例子中,是应用了工厂方法对第26章构造函数模式代码的改进版本: 复制代码 代码如下

随机推荐