cpp: Simple Factory Pattern

发布时间 2023-04-30 20:31:53作者: ®Geovin Du Dream Park™

 

// Monster.h : 此文件包含 "Monster" 类。Abstract Factory Pattern C++ 14
// 2023年4月29日 涂聚文 Geovin Du  Visual Studio 2022 edit.
#pragma once
#ifndef MONSTER_H 
#define MONSTER_H 



#include <iostream>


using namespace std;



namespace DuAbstractFactory
{

	/// <summary>
	/// 怪物父类
	/// </summary>
	class Monster
	{

	public:
		/// <summary>
		/// 构造函数
		/// </summary>
		/// <param name="life"></param>
		/// <param name="magic"></param>
		/// <param name="attack"></param>
		Monster(int life, int magic, int attack) :m_life(life), m_magic(magic), m_attack(attack) {}
		/// <summary>
		/// 做父类时析构函数应该为虚函数
		/// </summary>
		virtual ~Monster() {} 

	protected: //可能被子类访问的成员,用protected修饰
		//怪物属性

		/// <summary>
		/// 生命值
		/// </summary>
		int m_life;   
		/// <summary>
		/// 魔法值
		/// </summary>
		int m_magic;  

		/// <summary>
		/// 攻击力
		/// </summary>
		int m_attack;  


	};

}

#endif

// MonsterUndead.h : 此文件包含 "MonsterUndead" 类。Abstract Factory Methon Pattern C++ 14
// 2023年4月30日 涂聚文 Geovin Du edit.

#pragma once
#ifndef MONSTERUNDEAD_H 
#define MONSTERUNDEAD_H 



#include <iostream>
#include "Monster.h"

using namespace std;



namespace DuAbstractFactory
{

	/// <summary>
	/// 亡灵类怪物
	/// </summary>
	class MonsterUndead :public Monster
	{

	public:
		/// <summary>
		/// 构造函数
		/// </summary>
		/// <param name="life"></param>
		/// <param name="magic"></param>
		/// <param name="attack"></param>
		MonsterUndead(int life, int magic, int attack) :Monster(life, magic, attack)
		{
			cout << "一只亡灵类怪物来到了这个世界" << endl;
		}
		//其他代码略....

	};

}

#endif

// MonsterElement.h : 此文件包含 "MonsterElement" 类。Abstract Factory Methon Pattern C++ 14
// 2023年4月30日 涂聚文 Geovin Du edit.
#pragma once
#ifndef MONSTERELEMENT_H 
#define MONSTERELEMENT_H 



#include <iostream>
#include "Monster.h"

using namespace std;



namespace DuAbstractFactory
{
	/// <summary>
	/// 元素类怪物
	/// </summary>
	class MonsterElement:public Monster
	{

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

	};
}


#endif

// MonsterMechanic.h : 此文件包含 "MonsterMechanic" 类。Abstract Factory Methon Pattern C++ 14
// 2023年4月30日 涂聚文 Geovin Du edit.
#pragma once
#ifndef MONSTERMECHANIC_H 
#define MONSTERMECHANIC_H 



#include <iostream>
#include "Monster.h"

using namespace std;



namespace DuAbstractFactory
{

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

	};
}
#endif

// MonsterParFactoryMethod.h : 此文件包含 "MonsterParFactoryMethod" 类。Abstract Factory Methon Pattern C++ 14
// 2023年4月30日 涂聚文 Geovin Du edit.
#pragma once
#ifndef MONSTERPARFACTORYMETHOD_H 
#define MONSTERPARFACTORYMETHOD_H 



#include <iostream>
#include "Monster.h"
#include "MonsterUndead.h"
#include "MonsterElement.h"
#include "MonsterMechanic.h"

using namespace std;



namespace DuAbstractFactory
{
	/// <summary>
	/// 工厂方法模式
	/// </summary>
	class MonsterParFactoryMethod
	{

	public:

		/// <summary>
		/// 具体的实现在子类中进行
		/// </summary>
		/// <returns></returns>
		virtual Monster* createMonster() = 0; 

		/// <summary>
		/// 做父类时析构函数应该为虚函数
		/// </summary>
		virtual ~MonsterParFactoryMethod() {} 

	};


}


#endif

// MonsterSimpleFactory.h : 此文件包含 "MonsterSimpleFactory" 类。Abstract Factory Methon Pattern C++ 14
// 2023年4月30日 涂聚文 Geovin Du edit.
#pragma once
#ifndef MONSTERSIMPLEFACTORY_H 
#define MONSTERSIMPLEFACTORY_H 



#include <iostream>
#include "Monster.h"
#include "MonsterUndead.h"
#include "MonsterElement.h"
#include "MonsterMechanic.h"

using namespace std;



namespace DuAbstractFactory
{
	/// <summary>
	/// 简单工厂模式
	/// </summary>

	class MonsterSimpleFactory
	{

	public:
		/// <summary>
		/// 
		/// </summary>
		/// <param name="strmontype"></param>
		/// <returns></returns>
		Monster* createMonster(string strmontype)
		{
			Monster* prtnobj = nullptr;
			if (strmontype == "udd")  //udd代表要创建亡灵类怪物
			{
				prtnobj = new MonsterUndead(300, 50, 80);
			}
			else if (strmontype == "elm") //ele代表要创建元素类怪物
			{
				prtnobj = new MonsterElement(200, 80, 100);
			}
			else if (strmontype == "mec") //mec代表要创建机械类怪物
			{
				prtnobj = new MonsterMechanic(400, 0, 110);
			}
			return prtnobj;
		}


	};
}

#endif

// MonsterUndeadFactory.h : 此文件包含 "MonsterUndeadFactory" 类。Abstract Factory Methon Pattern C++ 14
// 2023年4月30日 涂聚文 Geovin Du edit.
#pragma once
#ifndef MONSTERUNDEADFACTORY_H 
#define MONSTERUNDEADFACTORY_H 



#include <iostream>
#include "Monster.h"
#include "MonsterUndead.h"
#include "MonsterElement.h"
#include "MonsterMechanic.h"
#include "MonsterParFactoryMethod.h"

using namespace std;



namespace DuAbstractFactory
{

	/// <summary>
	/// MonsterUndead怪物类型的工厂,生产MonsterUndead类型怪物
	/// </summary>
	class MonsterUndeadFactory : public MonsterParFactoryMethod
	{
	public:
		/// <summary>
		/// 创建亡灵类怪物
		/// </summary>
		/// <returns></returns>
		virtual Monster* createMonster()
		{


			return new MonsterUndead(300, 50, 80); 
		}

	};
}

#endif

// MonsterElementFactory.h : 此文件包含 "MonsterElementFactory" 类。Abstract Factory Methon Pattern C++ 14
// 2023年4月30日 涂聚文 Geovin Du edit.
#pragma once
#ifndef MONSTERELEMENTFACTORY_H 
#define MONSTERELEMENTFACTORY_H 



#include <iostream>
#include "Monster.h"
#include "MonsterUndead.h"
#include "MonsterElement.h"
#include "MonsterMechanic.h"
#include "MonsterParFactoryMethod.h"

using namespace std;



namespace DuAbstractFactory
{

	/// <summary>
	/// MonsterElement怪物类型的工厂,生产MonsterElement类型怪物
	/// </summary>
	class MonsterElementFactory : public MonsterParFactoryMethod
	{

	public:

		/// <summary>
		/// 创建元素类怪物
		/// </summary>
		/// <returns></returns>
		virtual Monster* createMonster()
		{
			return new MonsterElement(200, 80, 100); 
		}


	};





}

#endif

// MonsterElementFactory.h : 此文件包含 "MonsterElementFactory" 类。Abstract Factory Methon Pattern C++ 14
// 2023年4月30日 涂聚文 Geovin Du edit.
#pragma once
#ifndef MONSTERMECHANICFACTORY_H 
#define MONSTERMECHANICFACTORY_H 



#include <iostream>
#include "Monster.h"
#include "MonsterUndead.h"
#include "MonsterElement.h"
#include "MonsterMechanic.h"
#include "MonsterParFactoryMethod.h"

using namespace std;



namespace DuAbstractFactory
{

	/// <summary>
	/// MonsterMechanic怪物类型的工厂,生产MonsterMechanic类型怪物
	/// </summary>
	class MonsterMechanicFactory : public MonsterParFactoryMethod
	{
	public:

		/// <summary>
		/// 创建机械类怪物
		/// </summary>
		/// <returns></returns>
		virtual Monster* createMonster()
		{
			return new MonsterMechanic(400, 0, 110); 
		}


	};
}

#endif

// MonsterElementFactory.h : 此文件包含 "MonsterElementFactory" 类。Abstract Factory Methon Pattern C++ 14
// 2023年4月30日 涂聚文 Geovin Du edit.
#pragma once
#ifndef MONSTERCHILDFACTORY_H 
#define MONSTERCHILDFACTORY_H 



#include <iostream>
#include "Monster.h"
#include "MonsterUndead.h"
#include "MonsterElement.h"
#include "MonsterMechanic.h"
#include "MonsterParFactoryMethod.h"

using namespace std;



namespace DuAbstractFactory
{


	/// <summary>
	/// 创建怪物工厂子类模板
	/// </summary>
	/// <typeparam name="T"></typeparam>
	template <typename T>
	class MonsterChildFactory : public MonsterParFactoryMethod
	{
	public:
		virtual Monster* createMonster()
		{
			return new T(300, 50, 80);//如果需要不同的值则可以考虑通过createMonster的形参将值传递进来
		}
	};
	
}

#endif

  

// GeovinDu.h : 此文件包含 "GeovinDu" 类。Abstract Factory Methon Pattern C++ 14
// 2023年4月29日 涂聚文 Geovin Du edit.
#pragma once
#ifndef GEOVINDU_H 
#define GEOVINDU_H 

using namespace std;
namespace DuAbstractFactory
{

	/// <summary>
	/// 业务处理
	/// </summary>
	class GeovinDu
	{

	private:

	public:
		/// <summary>
		/// 简单工厂模式Simple factory model  pattern
		/// </summary>
		void displaySimpleFactory();
	};

}

#endif

// GeovinDu.cpp : 此文件包含 "GeovinDu" 类。Abstract Factory Methon Pattern C++ 14
// 2023年4月29日 涂聚文 Geovin Du edit.

#include "GeovinDu.h"
#include "Monster.h"
#include "MonsterUndead.h"
#include "MonsterElement.h"
#include "MonsterMechanic.h"
#include "MonsterParFactoryMethod.h"
#include "MonsterElementFactory.h"
#include "MonsterMechanicFactory.h"
#include "MonsterSimpleFactory.h"
#include "MonsterUndeadFactory.h"
#include "MonsterChildFactory.h"

using namespace std;

namespace DuAbstractFactory
{


	/// <summary>
	/// 全局的用于创建怪物对象的函数,注意形参的类型是工厂父类类型的指针,返回类型是怪物父类类型的指针
	/// </summary>
	/// <param name="factory"></param>
	/// <returns></returns>
	Monster* GlobalCreateMonster(MonsterParFactoryMethod* factory)
	{
		return factory->createMonster();//createMonster虚函数扮演了多态new的行为,factory指向的具体怪物工厂类不同,创建的怪物对象也不同
	}


	/// <summary>
	/// 简单工厂模式Simple factory model  pattern
	/// </summary>
	void GeovinDu::displaySimpleFactory()
	{


		/**/
		DuAbstractFactory::Monster* pM01 = new DuAbstractFactory::MonsterUndead(300, 50, 80); //产生了一只亡灵类怪物
		DuAbstractFactory::Monster* pM02 = new DuAbstractFactory::MonsterElement(200, 80, 100); //产生了一只元素类怪物
		DuAbstractFactory::Monster* pM03 = new DuAbstractFactory::MonsterMechanic(400, 0, 110); //产生了一只机械类怪物
		//释放资源
		delete pM01;
		delete pM02;
		delete pM03;


		/**/
		//简单工厂模式
		DuAbstractFactory::MonsterSimpleFactory facobj;
		DuAbstractFactory::Monster* pM11 = facobj.createMonster("udd"); //产生了一只亡灵类怪物,当然这里必须知道"udd"代表的是创建亡灵类怪物
		DuAbstractFactory::Monster* pM12 = facobj.createMonster("elm"); //产生了一只元素类怪物
		DuAbstractFactory::Monster* pM13 = facobj.createMonster("mec"); //产生了一只机械类怪物
		//释放资源
		delete pM11;
		delete pM12;
		delete pM13;


		/**/
		//工厂方法模式
		DuAbstractFactory::MonsterParFactoryMethod* p_ud_fy = new DuAbstractFactory::MonsterUndeadFactory(); //多态工厂,注意指针类型
		DuAbstractFactory::Monster* pM21 = GlobalCreateMonster(p_ud_fy);//产生了一只亡灵类怪物,也是多态,注意返回类型,当然也可以直接写成Monster* pM1 = p_ud_fy->createMonster();

		DuAbstractFactory::MonsterParFactoryMethod* p_elm_fy = new DuAbstractFactory::MonsterElementFactory();
		DuAbstractFactory::Monster* pM22 = GlobalCreateMonster(p_elm_fy);  //产生了一只元素类怪物

		DuAbstractFactory::MonsterParFactoryMethod* p_mec_fy = new DuAbstractFactory::MonsterMechanicFactory();
		DuAbstractFactory::Monster* pM23 = GlobalCreateMonster(p_mec_fy);  //产生了一只机械类怪物

		//释放资源
		//释放工厂
		delete p_ud_fy;
		delete p_elm_fy;
		delete p_mec_fy;

		//释放怪物
		delete pM21;
		delete pM22;
		delete pM23;


		/**/
		DuAbstractFactory::MonsterChildFactory<DuAbstractFactory::MonsterUndead> myFactory;
		DuAbstractFactory::Monster* pM10 = myFactory.createMonster();
		//释放资源
		delete pM10;

	}
}

  

调用:

// ConsoleDuAbstractFactory.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
// GeovinDu.cpp : 此文件包含 "GeovinDu" 类。Abstract Factory Methon Pattern C++ 14
// 2023年4月30日 涂聚文 Geovin Du Visual Studio 2022 edit. 文章来源《C++新经典设计模式》 王健伟编著 清华大学出版社 


#define _UNICODE

#include <iostream>

#include "Monster.h"
#include "MonsterUndead.h"
#include "MonsterElement.h"
#include "MonsterMechanic.h"
#include "MonsterParFactoryMethod.h"
#include "MonsterElementFactory.h"
#include "MonsterMechanicFactory.h"
#include "MonsterSimpleFactory.h"
#include "MonsterUndeadFactory.h"
#include "MonsterChildFactory.h"
#include "GeovinDu.h"

using namespace std;
using namespace DuAbstractFactory;



int main()
{
    std::cout << "Hello World! 涂聚文 Geovin Du\n";


	_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);//程序退出时检测内存泄漏并显示到“输出”窗口

	GeovinDu geovindu;
	geovindu.displaySimpleFactory();


	system("pause");

	return 0;
	
}

// 运行程序: Ctrl + F5 或调试 >“开始执行(不调试)”菜单
// 调试程序: F5 或调试 >“开始调试”菜单

// 入门使用技巧: 
//   1. 使用解决方案资源管理器窗口添加/管理文件
//   2. 使用团队资源管理器窗口连接到源代码管理
//   3. 使用输出窗口查看生成输出和其他消息
//   4. 使用错误列表窗口查看错误
//   5. 转到“项目”>“添加新项”以创建新的代码文件,或转到“项目”>“添加现有项”以将现有代码文件添加到项目
//   6. 将来,若要再次打开此项目,请转到“文件”>“打开”>“项目”并选择 .sln 文件
#define UNICODE

  

输出: