cpp: Memento Pattern

 

/*****************************************************************//**
 * \file   ActorMemento.h
 * \brief   備忘錄模式 Memento Pattern亦稱:快照、Snapshot、Memento  C++ 14
 * 2023年6月6日 塗聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef ACTORMEMENTO_H 
#define ACTORMEMENTO_H 

#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>


using namespace std;




namespace DuMementoPattern
{

	/// <summary>
	/// 
	/// </summary>
	class ActorMemento
	{
	private:
		//

		/// <summary>
		/// 構造函數,用private修飾以防止在外部被隨意創建
		/// </summary>
		/// <param name="life"></param>
		/// <param name="magic"></param>
		/// <param name="face"></param>
		ActorMemento(int life, int magic, int face) :mLife(life), mMagic(magic), mfaceScore(face) {}

	private:
		//提供一些供Fighter類來訪問的接口,用private修飾防止被任意類訪問

		/// <summary>
		/// 友元類Fighter可以訪問本類的私有成員函數
		/// </summary>
		friend class ActorFighter; 
		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		int getLife() const { return mLife; }
		/// <summary>
		/// 
		/// </summary>
		/// <param name="life"></param>
		void setLife(int life) { mLife = life; }
		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		int getMagic() const { return mMagic; }
		/// <summary>
		/// 
		/// </summary>
		/// <param name="magic"></param>
		void setMagic(int magic) { mMagic = magic; }

		/// <summary>
		/// 
		/// </summary>
		/// <returns></returns>
		int getFaceScore() const { return mfaceScore; }
		/// <summary>
		/// 
		/// </summary>
		/// <param name="face"></param>
		void getFaceScore(int face) { mfaceScore = face; }
	private:
		/// <summary>
		/// 生命值
		/// </summary>
		int mLife;    
		/// <summary>
		/// 魔法值
		/// </summary>
		int mMagic;   
		/// <summary>
		/// 顏值
		/// </summary>
		int mfaceScore;  


	};

}

#endif

/*****************************************************************//**
 * \file   ActorFighter.h
 * \brief   備忘錄模式 Memento Pattern亦稱:快照、Snapshot、Memento  C++ 14
 * 2023年6月6日 塗聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef ACTORFIGHTER_H 
#define ACTORFIGHTER_H 

#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>

#include "ActorMemento.h"

using namespace std;




namespace DuMementoPattern
{

	/// <summary>
	/// 
	/// </summary>
	class ActorFighter
	{
	public:
		/// <summary>
		/// 構造函數
		/// </summary>
		/// <param name="life"></param>
		/// <param name="magic"></param>
		/// <param name="face"></param>
		ActorFighter(int life, int magic, int face) :mLife(life), mMagic(magic), mfaceScore(face) {}


	public:
		/// <summary>
		/// 將數據寫入備忘錄(創建備忘錄,並在其中存儲了當前狀態)
		/// </summary>
		/// <returns></returns>
		ActorMemento* createMomento()
		{
			return new ActorMemento(mLife, mMagic, mfaceScore);
		}
		/// <summary>
		/// 從備忘錄中恢復玩家數據
		/// </summary>
		/// <param name="pfm"></param>
		void restoreMomento(ActorMemento* pfm)
		{
			mLife = pfm->getLife();
			mMagic = pfm->getMagic();
			mfaceScore = pfm->getFaceScore();
		}
		/// <summary>
		/// 爲測試目的引入的接口,設置生命值爲0
		/// </summary>
		void setToDead()
		{
			mLife = 0;
		}
		/// <summary>
		/// 用於輸出一些信息
		/// </summary>
		void displayInfo()
		{
			cout << "主角當前的生命值、魔法值、顏值分別爲:" << mLife << "," << mMagic << "," << mfaceScore << endl;
		}


	private:
		//角色屬性
		/// <summary>
		/// 生命值
		/// </summary>
		int mLife;
		/// <summary>
		/// 魔法值
		/// </summary>
		int mMagic;
		/// <summary>
		/// 顏值
		/// </summary>
		int mfaceScore;
		//......其他數據略



	};

}

#endif

/*****************************************************************//**
 * \file   ActorCareTaker.h
 * \brief   備忘錄模式 Memento Pattern亦稱:快照、Snapshot、Memento  C++ 14
 * 2023年6月6日 塗聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef ACTORCARETAKER_H 
#define ACTORCARETAKER_H 

#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>

#include "ActorMemento.h"

using namespace std;




namespace DuMementoPattern
{

	/// <summary>
	/// 管理者(負責人)類
	/// </summary>
	class ActorCareTaker
	{

	public:
		/// <summary>
		/// 構造函數
		/// </summary>
		/// <param name="ptmpfm"></param>
		ActorCareTaker(ActorMemento* ptmpfm) :m_pfm(ptmpfm) {} //形參是指向備忘錄對象的指針

		/// <summary>
		/// 獲取指向備忘錄對象的指針
		/// </summary>
		/// <returns></returns>
		ActorMemento* getMemento()
		{
			return m_pfm;
		}
		/// <summary>
		/// 保存指向備忘錄對象的指針
		/// </summary>
		/// <param name="ptmpfm"></param>
		void setMemento(ActorMemento* ptmpfm)
		{
			m_pfm = ptmpfm;
		}
	private:
		ActorMemento* m_pfm; //指向備忘錄對象的指針


	};

}

#endif

/*****************************************************************//**
 * \file   MultipleSnapshotsCareTaker.h
 * \brief   備忘錄模式 Memento Pattern亦稱:快照、Snapshot、Memento  C++ 14
 * 2023年6月6日 塗聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef MULTIPLESNAPSHOTSCARETAKER_H 
#define MULTIPLESNAPSHOTSCARETAKER_H 

#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>

#include "ActorMemento.h"

using namespace std;




namespace DuMementoPattern
{

	/// <summary>
	/// 支持多個快照的負責人(管理者)類
	/// </summary>
	class MultipleSnapshotsCareTaker
	{


	public:
		/// <summary>
		/// 析構函數用於釋放資源
		/// </summary>
		~MultipleSnapshotsCareTaker()
		{
			for (auto iter = m_pfmContainer.begin(); iter != m_pfmContainer.end(); ++iter)
			{
				delete (*iter);
			} //end for
		}
		/// <summary>
		/// 保存指向備忘錄對象的指針
		/// </summary>
		/// <param name="ptmpfm"></param>
		void setMemento(ActorMemento* ptmpfm)
		{
			m_pfmContainer.push_back(ptmpfm);
		}
		/// <summary>
		/// 獲取指向備忘錄對象的指針
		/// </summary>
		/// <param name="index"></param>
		/// <returns></returns>
		ActorMemento* getMemento(int index)
		{
			auto iter = m_pfmContainer.begin();
			for (int i = 0; i <= index; ++i)
			{
				if (i == index)
					return (*iter);
				else
					++iter;
			} //end for	
			return NULL;
		}
	private:
		/// <summary>
		/// 存儲備忘錄對象指針的容器
		/// </summary>
		vector<ActorMemento*> m_pfmContainer;  //#include <vector>


	};

}


#endif

/*****************************************************************//**
 * \file   GeovinDu.h
 * \brief  備忘錄模式 Memento Pattern亦稱:快照、Snapshot、Memento  C++ 14
 * 2023年6月6日 塗聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#pragma once
#ifndef GEOVINDU_H 
#define GEOVINDU_H 

#include<cstring>
#include<stdbool.h>
#include<stdlib.h>
#include<iostream>
#include<malloc.h>
#include<cmath>
#include <iostream>
#include <sstream>
#include <vector>
#include <algorithm>
#include <array>
#include <functional>
#include <list>
#include <string>
#include <string.h>
#include <vector>
#include <map>

#include "ActorCareTaker.h"
#include "ActorFighter.h"
#include "ActorMemento.h"
#include "MultipleSnapshotsCareTaker.h"



using namespace std;



namespace DuMementoPattern
{

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

	private:

	public:

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

		/// <summary>
		/// 
		/// </summary>
		void displayDuSimple();

	};
}
#endif

/*****************************************************************//**
 * \file   GeovinDu.cpp
 * \brief  備忘錄模式 Memento Pattern亦稱:快照、Snapshot、Memento  C++ 14
 * 2023年6月6日 塗聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
#include "GeovinDu.h"


using namespace std;




namespace DuMementoPattern
{

	/// <summary>
	/// 
	/// </summary>
	void GeovinDu::displaySimple()
	{
		DuMementoPattern::ActorFighter* p_fighter = new DuMementoPattern::ActorFighter(800, 200, 300);
		//(1)顯示玩家主角在與BOSS戰鬥之前的信息
		p_fighter->displayInfo();

		//(2)爲玩家主角類對象創建一個備忘錄對象(其中保存了當前主角類對象中的必要信息)
		//_nmsp1::FighterMemento* p_fighterMemo = p_fighter->createMomento();
		DuMementoPattern::ActorCareTaker* pfcaretaker = new DuMementoPattern::ActorCareTaker(p_fighter->createMomento());

		//(3)玩家與BOSS開始戰鬥
		cout << "主角與BOSS開始進行激烈的飆戲------" << endl;
		p_fighter->setToDead();   //主角在與BOSS戰鬥中,生命值最終變成0而死亡(被BOSS擊敗)
		p_fighter->displayInfo(); //顯示玩家主角在與BOSS戰鬥之後的信息

		//(4)因爲在與BOSS戰鬥之前已經通過NPC保存了遊戲進度,這裏模擬載入遊戲進度,恢復玩家主角類對象的數據,讓其可以與BOSS再次戰鬥
		cout << "主角通過備忘錄恢復自己的信息------" << endl;
		//p_fighter->restoreMomento(p_fighterMemo);
		p_fighter->restoreMomento(pfcaretaker->getMemento());
		p_fighter->displayInfo(); //顯示玩家主角通過備忘錄恢復到戰鬥之前的信息

		//(5)釋放資源
		//delete p_fighterMemo;
		delete pfcaretaker->getMemento();
		delete pfcaretaker; //新增
		delete p_fighter;

	}
	/// <summary>
	/// 
	/// </summary>
	void GeovinDu::displayDuSimple()
	{
		DuMementoPattern::ActorFighter* p_fighter2 = new DuMementoPattern::ActorFighter(800, 200, 300);
		DuMementoPattern::MultipleSnapshotsCareTaker* pfcaretaker2 = new DuMementoPattern::MultipleSnapshotsCareTaker();
		pfcaretaker2->setMemento(p_fighter2->createMomento()); //做第一次快照嗎,此快照玩家生命值爲800
		p_fighter2->setToDead(); //改變玩家主角的生命值
		pfcaretaker2->setMemento(p_fighter2->createMomento()); //做第二次快照,此快照玩家生命值爲0
		p_fighter2->displayInfo(); //玩家主角生命值應該爲0
		cout << "------------------" << endl;
		//當前玩家生命值爲0,恢復第一次快照,也就是恢復玩家生命值爲800	
		p_fighter2->restoreMomento(pfcaretaker2->getMemento(0));
		p_fighter2->displayInfo(); //玩家主角生命值應該恢復爲800

		//釋放資源
		delete p_fighter2;
		delete pfcaretaker2;

	}

}

  

調用:

/*****************************************************************//**
 * \file   ConsoleDuMementoPattern.cpp
 * \brief  備忘錄模式 Memento Pattern亦稱:快照、Snapshot、Memento  C++ 14
 * 2023年6月6日 塗聚文 Geovin Du Visual Studio 2022 edit.
 * \author geovindu
 * \date   June 2023
 *********************************************************************/
// ConsoleDuMementoPattern.cpp : 此文件包含 "main" 函數。程序執行將在此處開始並結束。
//
#define _UNICODE

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

using namespace std;
using namespace DuMementoPattern;



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

    geovin.displaySimple();

    cout << "**********" << endl;
    geovin.displayDuSimple();

    system("pause");

    return 0;
}


// 運行程序: Ctrl + F5 或調試 >“開始執行(不調試)”菜單
// 調試程序: F5 或調試 >“開始調試”菜單

// 入門使用技巧: 
//   1. 使用解決方案資源管理器窗口添加/管理文件
//   2. 使用團隊資源管理器窗口連接到源代碼管理
//   3. 使用輸出窗口查看生成輸出和其他消息
//   4. 使用錯誤列表窗口查看錯誤
//   5. 轉到“項目”>“添加新項”以創建新的代碼文件,或轉到“項目”>“添加現有項”以將現有代碼文件添加到項目
//   6. 將來,若要再次打開此項目,請轉到“文件”>“打開”>“項目”並選擇 .sln 文件
#define UNICODE

  

輸出:

Hello World!塗聚文 Geovin Du
主角當前的生命值、魔法值、顏值分別爲:800,200,300
主角與BOSS開始進行激烈的飆戲------
主角當前的生命值、魔法值、顏值分別爲:0,200,300
主角通過備忘錄恢復自己的信息------
主角當前的生命值、魔法值、顏值分別爲:800,200,300
**********
主角當前的生命值、魔法值、顏值分別爲:0,200,300
------------------
主角當前的生命值、魔法值、顏值分別爲:800,200,300
請按任意鍵繼續. . .

  

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章