cpp: State Pattern

发布时间 2023-05-29 23:23:03作者: ®Geovin Du Dream Park™

 

/*****************************************************************//**
 * \file   Gold.h
 * \brief  State Pattern 状态模式  C++ 14
 * 2023年5月29日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   May 2023
 *********************************************************************/
#pragma once
#ifndef GOLD_H 
#define GOLD_H 




#include <iostream>


using namespace std;




namespace DuJewelryStatePattern
{
	class GoldStatus;
	/// <summary>
	/// 液态 固态 气态  无态   solid, liquid and gas  stateless
	/// </summary>
	class Gold
	{

	public:
		Gold(int life);
		~Gold();

	public:
		/// <summary>
		/// 
		/// </summary>
		/// <param name="power"></param>
		void Liked(int power);  

	public:
		/// <summary>
		/// 获取生命值
		/// </summary>
		/// <returns></returns>
		int GetBoilingPoint() //
		{
			return mBoilingPoint;
		}
		/// <summary>
		/// 设置生命值
		/// </summary>
		/// <param name="life"></param>
		void SetBoilingPoint(int life)
		{
			mBoilingPoint = life;
		}

		/// <summary>
		/// 获取当前状态
		/// </summary>
		/// <returns></returns>
		GoldStatus* getCurrentState() 
		{
			return mState;
		}

		/// <summary>
		/// 设置当前状态
		/// </summary>
		/// <param name="pstate"></param>
		void setCurrentState(GoldStatus* pstate) 
		{
			mState = pstate;
		}

	private:
		/// <summary>
		/// 沸點
		/// </summary>
		int  mBoilingPoint;
		/// <summary>
		/// 持有状态对象
		/// </summary>
		GoldStatus* mState;  



	};

}


#endif

/*****************************************************************//**
 * \file   Gold.cpp
 * \brief    State Pattern 状态模式  C++ 14
 *  2023年5月29日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   May 2023
 *********************************************************************/

#include "Gold.h"
#include "GoldStatusLiquid.h"


using namespace std;




namespace DuJewelryStatePattern
{

	/// <summary>
	/// 构造函数,怪物的初始状态
	/// </summary>
	/// <param name="life"></param>
	Gold::Gold(int life) :mBoilingPoint(life), mState(nullptr)
	{
		//mState = new GoldStatusLiquid();
		mState = GoldStatusLiquid::getInstance();
	}

	/// <summary>
	/// 析构函数
	/// </summary>
	Gold::~Gold()
	{
		//delete m_pState;
	}

	//怪物被攻击

	void Gold::Liked(int power)
	{
		/*
		int orglife = mBoilingPoint; //暂存原来的怪物血量值用于后续比较
		mBoilingPoint -= power;      //怪物剩余的血量
		if (orglife > 400)    //怪物原来处于凶悍状态
		{
			if (mBoilingPoint > 400) //状态未变
			{
				//cout << "怪物受到" << power << "点伤害并对主角进行疯狂的反击!" << endl;
				mState->Liked(power, this); //其他的逻辑代码被本Monster类委托给了具体状态类来处理
			}
			else if (mBoilingPoint > 100) //状态从凶悍改变到不安
			{
				//cout << "怪物受到" << power << "点伤害并对主角进行反击,怪物变得焦躁不安并开始呼唤支援!" << endl;
				delete mState; //释放原有的状态对象
				mState = new GoldStatusGas(); //怪物转到不安状态
				mState->Liked(power, this);
			}
			else if (mBoilingPoint > 0)//状态从凶悍状态改变到恐惧状态,主角的攻击太恐怖了
			{
				//cout << "怪物受到" << power << "点伤害,怪物变得恐惧并开始逃跑!" << endl;
				delete mState; //释放原有的状态对象
				mState = new GoldStatusSolid(); //怪物转到恐惧状态
				mState->Liked(power, this);
			}
			else//状态从凶悍改变到死亡
			{
				//cout << "怪物受到" << power << "点伤害,已经死亡!" << endl;
				delete mState; //释放原有的状态对象
				mState = new GoldStatusStateless(); //怪物转到死亡状态
				mState->Liked(power, this);
			}
		}
		else if (orglife > 100) //怪物原来处于不安状态
		{
			if (mBoilingPoint > 100) //状态未变
			{
				//cout << "怪物受到" << power << "点伤害并对主角进行反击,并继续急促的呼唤支援!" << endl;
				mState->Liked(power, this);
			}
			else if (mBoilingPoint > 0)//状态从不安改变到恐惧
			{
				//cout << "怪物受到" << power << "点伤害,怪物变得恐惧并开始逃跑!" << endl;
				delete mState; //释放原有的状态对象
				mState = new GoldStatusSolid(); //怪物转到恐惧状态
				mState->Liked(power, this);
			}
			else//状态从不安改变到死亡
			{
				//cout << "怪物受到" << power << "点伤害,已经死亡!" << endl;
				delete mState; //释放原有的状态对象
				mState = new GoldStatusStateless(); //怪物转到死亡状态
				mState->Liked(power, this);
			}
		}
		else if (orglife > 0) //怪物原来处于恐惧状态
		{
			if (mBoilingPoint > 0)//状态未变
			{
				//cout << "怪物受到" << power << "点伤害,怪物继续逃跑!" << endl;
				mState->Liked(power, this);
			}
			else//状态从恐惧改变到死亡
			{
				//cout << "怪物受到" << power << "点伤害,已经死亡!" << endl;
				delete mState; //释放原有的状态对象
				mState = new GoldStatusStateless(); //怪物转到死亡状态
				mState->Liked(power, this);
			}
		}
		else //怪物已经死亡
		{
			//已经死亡的怪物,状态不会继续发生改变
			//cout << "怪物已死亡,不能再被攻击!" << endl;
			mState->Liked(power, this);
		}
		*/
		mState->Liked(power, this);

	}

}

#pragma once
#ifndef GOLDSTATUS_H 
#define GOLDSTATUS_H 




#include <iostream>


using namespace std;




namespace DuJewelryStatePattern
{

	/// <summary>
	/// 
	/// </summary>
	class Gold;
	/// <summary>
	/// 
	/// </summary>
	class GoldStatus
	{
	public:
		/// <summary>
		/// 
		/// </summary>
		/// <param name="power"></param>
		/// <param name="mainobj"></param>
		virtual void Liked(int power, Gold* mainobj) = 0;
		/// <summary>
		/// 
		/// </summary>
		virtual ~GoldStatus() {}
	};
	

}

#endif

/*****************************************************************//**
 * \file   GoldStatusStateless.h
 * \brief  State Pattern 状态模式  C++ 14
 * 2023年5月29日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   May 2023
 *********************************************************************/
#pragma once
#ifndef GOLDSTATUSSTATELESS_H 
#define GOLDSTATUSSTATELESS_H 




#include <iostream>
#include "Gold.h"
#include "GoldStatus.h"

using namespace std;




namespace DuJewelryStatePattern
{

	/// <summary>
	/// 
	/// </summary>
	class GoldStatusStateless:public GoldStatus
	{
	public:
		virtual void Liked(int power, Gold* mainobj);

	public:
		static GoldStatusStateless* getInstance()
		{
			static GoldStatusStateless instance;
			return &instance;
		}


	};

}

#endif

/*****************************************************************//**
 * \file   GoldStatusStateless.cpp
 * \brief  State Pattern 状态模式  C++ 14
 * 2023年5月29日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   May 2023
 *********************************************************************/
#include "GoldStatusStateless.h"
using namespace std;




namespace DuJewelryStatePattern
{


	/// <summary>
	/// 
	/// </summary>
	/// <param name="power"></param>
	/// <param name="mainobj"></param>
	void GoldStatusStateless::Liked(int power, Gold* mainobj)
	{
		int orglife = mainobj->GetBoilingPoint();
		if (orglife > 0)
		{
			//
			mainobj->SetBoilingPoint(orglife - power); //无态
			//处理等
		}
		cout << "无形之中!" << std::endl;
	}

}

/*****************************************************************//**
 * \file   GoldStatusSolid.h
 * \brief  State Pattern 状态模式  C++ 14
 * 2023年5月29日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   May 2023
 *********************************************************************/
#pragma once
#ifndef GOLDSTATUSSOLID_H 
#define GOLDSTATUSSOLID_H 




#include <iostream>
#include "Gold.h"
#include "GoldStatus.h"
#include "GoldStatusGas.h"
#include "GoldStatusStateless.h"

using namespace std;




namespace DuJewelryStatePattern
{

	/// <summary>
	/// 
	/// </summary>
	class GoldStatusSolid :public GoldStatus
	{
	public:
		virtual void Liked(int power, Gold* mainobj);

	public:
		static GoldStatusSolid* getInstance()
		{
			static GoldStatusSolid instance;
			return &instance;
		}

	};
}

#endif


/*****************************************************************//**
 * \file   GoldStatusSolid.cpp
 * \brief  State Pattern 状态模式  C++ 14
 * 2023年5月29日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   May 2023
 *********************************************************************/

#include "GoldStatusSolid.h"
using namespace std;




namespace DuJewelryStatePattern
{
	/// <summary>
	/// 
	/// </summary>
	/// <param name="power"></param>
	/// <param name="mainobj"></param>
	void GoldStatusSolid::Liked(int power, Gold* mainobj)
	{
		int orglife = mainobj->GetBoilingPoint();
		if ((orglife - power) > 0)       //
		{
			//状态未变
			mainobj->SetBoilingPoint(orglife - power); //液态
			cout << "处于液态状态中,随处都有其容入之处!" << std::endl;
			//处理其他动作逻辑比如逃跑
		}
		else
		{
			//不管下个状态是啥,总之不会是凶悍、不安和恐惧状态,只可能是死亡状态
			//delete mainobj->getCurrentState();
			//mainobj->setCurrentState(new GoldStatusDead);
			mainobj->setCurrentState(GoldStatusStateless::getInstance());
			mainobj->getCurrentState()->Liked(power, mainobj);
		}
	}

}

/*****************************************************************//**
 * \file   GoldStatusLiquid.h
 * \brief  State Pattern 状态模式  C++ 14
 * 2023年5月29日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   May 2023
 *********************************************************************/
#pragma once
#ifndef GOLDSTATUSFEROC_H 
#define GOLDSTATUSFEROC_H 




#include <iostream>
#include "Gold.h"
#include "GoldStatus.h"

#include "GoldStatusGas.h"

using namespace std;




namespace DuJewelryStatePattern
{
	/// <summary>
	/// 
	/// </summary>
	class GoldStatusLiquid:public GoldStatus
	{

	public:
		virtual void Liked(int power, Gold* mainobj);


	public:
		static GoldStatusLiquid* getInstance()
		{
			static GoldStatusLiquid instance;
			return &instance;
		}

	};

}
#endif

/*****************************************************************//**
 * \file   GoldStatusSolid.cpp
 * \brief  State Pattern 状态模式  C++ 14
 * 2023年5月29日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   May 2023
 *********************************************************************/

#include "GoldStatusSolid.h"
using namespace std;




namespace DuJewelryStatePattern
{
	/// <summary>
	/// 
	/// </summary>
	/// <param name="power"></param>
	/// <param name="mainobj"></param>
	void GoldStatusSolid::Liked(int power, Gold* mainobj)
	{
		int orglife = mainobj->GetBoilingPoint();
		if ((orglife - power) > 0)       //
		{
			//状态未变
			mainobj->SetBoilingPoint(orglife - power); //液态
			cout << "处于液态状态中,随处都有其容入之处!" << std::endl;
			//处理其他动作逻辑比如逃跑
		}
		else
		{
			//不管下个状态是啥,总之不会是凶悍、不安和恐惧状态,只可能是死亡状态
			//delete mainobj->getCurrentState();
			//mainobj->setCurrentState(new GoldStatusDead);
			mainobj->setCurrentState(GoldStatusStateless::getInstance());
			mainobj->getCurrentState()->Liked(power, mainobj);
		}
	}

}

/*****************************************************************//**
 * \file   GoldStatusGas.h
 * \brief  State Pattern 状态模式  C++ 14
 * 2023年5月29日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   May 2023
 *********************************************************************/
#pragma once
#ifndef GOLDSTATUSGAS_H 
#define GOLDSTATUSGAS_H 




#include <iostream>
#include "Gold.h"
#include "GoldStatus.h"
#include "GoldStatusSolid.h"

using namespace std;




namespace DuJewelryStatePattern
{

	/// <summary>
	/// 
	/// </summary>
	class GoldStatusGas:public GoldStatus
	{
	public:
		virtual void Liked(int power, Gold* mainobj);

	public:
		static GoldStatusGas* getInstance()
		{
			static GoldStatusGas instance;
			return &instance;
		}


	};
}
#endif

/*****************************************************************//**
 * \file   GoldStatusGas.cpp
 * \brief  State Pattern 状态模式  C++ 14
 * 2023年5月29日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   May 2023
 *********************************************************************/
#include "GoldStatusGas.h"
using namespace std;




namespace DuJewelryStatePattern
{


	/// <summary>
	/// 
	/// </summary>
	/// <param name="power"></param>
	/// <param name="mainobj"></param>
	void GoldStatusGas::Liked(int power, Gold* mainobj)
	{
		int orglife = mainobj->GetBoilingPoint();
		if ((orglife - power) > 100)       //怪物原来处于不安状态,现在依旧处于不安状态
		{
			//状态未变
			mainobj->SetBoilingPoint(orglife - power); //气态
			cout << "处于气态状态中,可以四处飘溢!" << std::endl;
			//处理其他动作逻辑比如反击和不停的呼唤支援
		}
		else
		{
			//不管下个状态是啥,总之不会是凶悍和不安状态,只可能是恐惧、死亡状态之一,先无条件转到恐惧状态去
			//delete mainobj->getCurrentState();
			//mainobj->setCurrentState(new GoldStatusFear);
			mainobj->setCurrentState(GoldStatusSolid::getInstance());
			mainobj->getCurrentState()->Liked(power, mainobj);
		}
	}

}

/*****************************************************************//**
 * \file   Pear.h
 * \brief   State Pattern 状态模式  C++ 14
 * 2023年5月29日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   May 2023
 *********************************************************************/

#pragma once

#ifndef PEAR_H 
#define PEAR_H 




#include <iostream>
#include "Gold.h"
#include "GoldStatus.h"
#include "GoldStatusGas.h"
#include "GoldStatusStateless.h"

using namespace std;




namespace DuJewelryStatePattern
{

	//怪物状态枚举值
	enum PearState
	{
		/// <summary>
		/// 液态
		/// </summary>
		Solid, 
		/// <summary>
		/// 固态
		/// </summary>
		Liquid, 
		/// <summary>
		/// 气态
		/// </summary>
		Gas,
		/// <summary>
		/// 无态
		/// </summary>
		Stateless
	};

	/// <summary>
	/// 
	/// </summary>
	class Pear
	{

	public:
		//构造函数,怪物的初始状态从“凶悍”开始
		Pear(int life) :mBoilingPoint(life), mStatus(Solid) {}

	public:
		/// <summary>
		/// 
		/// </summary>
		/// <param name="power"></param>
		void Liked(int power)
		{
			mBoilingPoint -= power; 
			if (mStatus == Solid)
			{
				if (mBoilingPoint > 400)
				{
					cout << "液态" << power << " 可以熔炼制工!" << endl;
					//处理其他动作逻辑
				}
				else if (mBoilingPoint > 100)
				{
					cout << "固态" << power << "可以制作精美饰物!" << endl;
					mStatus = Liquid;
					//处理其他动作逻辑
				}
				else if (mBoilingPoint > 0)
				{
					cout << "气态" << power << "可以无处不飘溢!" << endl;
					mStatus = Gas;
					//处理其他动作逻辑
				}
				else
				{
					cout << "无态" << power << "无所不在!" << endl;
					mStatus = Stateless;
					//处理等
				}
			}
			else if (mStatus == Liquid)
			{
				if (mBoilingPoint > 100)
				{
					cout << "固态" << power << "可以制作精美饰物!" << endl;
					//处理其他动作逻辑
				}
				else if (mBoilingPoint > 0)
				{
					cout << "气态" << power << "可以无处不飘溢!" << endl;
					mStatus = Gas;
					//处理其他动作逻辑
				}
				else
				{
					cout << "无态" << power << "无所不在!" << endl;
					mStatus = Stateless;
					//处理等
				}
			}
			else if (mStatus == Solid)
			{
				if (mBoilingPoint > 0)
				{
					cout << "固态" << power << "可以制作精美饰物!" << endl;
					//处理其他动作逻辑比如
				}
				else
				{
					cout << "无态" << power << "无所不在!" << endl;
					mStatus = Stateless;
					//处理等
				}
			}
			else 
			{
				cout << "无态,无所不在!" << endl;
			}
		}
	private:

		/// <summary>
		/// 沸点
		/// </summary>
		int  mBoilingPoint;   
		/// <summary>
		/// 初始状态
		/// </summary>
		PearState   mStatus; 



	};

}

#endif

/*****************************************************************//**
 * \file   GeovinDu.h
 * \brief  State Pattern 状态模式  C++ 14
 * 2023年5月29日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   May 2023
 *********************************************************************/
#pragma once
#ifndef GEOVINDU_H 
#define GEOVINDU_H 




#include <iostream>
#include "Gold.h"
#include "GoldStatus.h"
#include "GoldStatusGas.h"
#include "GoldStatusStateless.h"
#include "Pear.h"


using namespace std;




namespace DuJewelryStatePattern
{

	/// <summary>
	/// 
	/// </summary>
	class GeovinDu
	{

	private:

	public:

		/// <summary>
		/// 
		/// </summary>
		void displaySimple();
		/// <summary>
		/// 
		/// </summary>
		void displayPearSimple();


	};

}

#endif

/*****************************************************************//**
 * \file   GeovinDu.cpp
 * \brief  State Pattern 状态模式  C++ 14
 * 2023年5月29日 涂聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   May 2023
 *********************************************************************/
#include "GeovinDu.h"
using namespace std;




namespace DuJewelryStatePattern
{


	/// <summary>
	/// 
	/// </summary>
	void GeovinDu::displaySimple()
	{

		Gold gold(500);
		cout << "黃金礦挖取,当前处于升華状态,500点!" << endl;
		gold.Liked(20);
		gold.Liked(100);
		gold.Liked(200);
		gold.Liked(170);
		gold.Liked(100);
		gold.Liked(100);

	}
	/// <summary>
	/// 
	/// </summary>
	void GeovinDu::displayPearSimple()
	{
		DuJewelryStatePattern::Pear pear(500);
		cout << "美好状态,500点!" << endl;
		pear.Liked(20);
		pear.Liked(100);
		pear.Liked(200);
		pear.Liked(170);
		pear.Liked(100);
		pear.Liked(100);

	}


}

  

调用:

// ConsoleDuStatePattern.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#define _UNICODE

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

#ifdef _DEBUG   //只在Debug(调试)模式下
#ifndef DEBUG_NEW
#define DEBUG_NEW new(_NORMAL_BLOCK,__FILE__,__LINE__) //重新定义new运算符
#define new DEBUG_NEW
#endif
#endif

using namespace std;
using namespace DuJewelryStatePattern;


int main()
{
    std::cout << "Hello World!涂聚文 Geovin Du\n";
    GeovinDu geovin;
    geovin.displaySimple();
    cout << "***********" << endl;
    geovin.displayPearSimple();
    system("pause");

    return 0;

}

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

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

  

输出

Hello World!涂聚文 Geovin Du
黃金礦挖取,当前处于升華状态,500点!
处于固状态中,可以制作精美器物!
处于气态状态中,可以四处飘溢!
处于气态状态中,可以四处飘溢!
处于液态状态中,随处都有其容入之处!
无形之中!
无形之中!
***********
美好状态,500点!
液态20 可以熔炼制工!
固态100可以制作精美饰物!
固态200可以制作精美饰物!
气态170可以无处不飘溢!
无态,无所不在!
无态,无所不在!
请按任意键继续. . .