Bootstrap

C++二十三种设计模式之备忘录模式

C++二十三种设计模式之备忘录模式

一、组成

原发器类:具备生成备忘录对象和从备忘录对象恢复相关信息的功能。
备忘录类:存储原发器类相关信息。
备忘录管理者类:存储备忘录类对象。

二、特点

1.备忘录类构造函数和数据设置为私有权限,防止备忘录类对象被随意创建,防止数据被随便修改。

三、目的

不暴露原发器类实现细节的情况下保存和恢复原发器对象的数据。

四、缺点

1、内存占用问题,如果需要保存的备忘录对象数量多会占用较多内存。
2、状态管理问题,需要知道原发器对象从哪个状态备份,又用于哪个状态。

五、示例代码

#include<iostream>
#include <vector>
#include <list>
#include <string>
#include <mutex>
#include <map>
#include<stack>

using namespace std;

class Fighter;
class FMememento;
class FCareTaker;

class FMememento {
private:
	FMememento(int life, int attack, int magic) :m_life(life), m_attack(attack), m_magic(magic) {}
	~FMememento() {}
	friend class Fighter;

	void SetLife(int life) {
		m_life = life;
	}
	void SetAttack(int attack) {
		m_attack = attack;
	}
	void SetMagic(int magic) {
		m_magic = magic;
	}
	int getLife() {
		return m_life;
	}
	int getAttack() {
		return m_attack;
	}
	int getMagic() {
		return m_magic;
	}

	int m_life;
	int m_attack;
	int m_magic;
};

class Fighter {
private:
	Fighter() {};
public:
	Fighter(int life, int attack, int magic) :m_life(life), m_attack(attack), m_magic(magic) {};
	FMememento* createMemento() {
		return new FMememento(m_life, m_attack, m_magic);
	}
	void restoreMemento(FMememento* mememento) {
		m_life = mememento->getLife();
		m_attack = mememento->getAttack();
		m_magic = mememento->getMagic();
	}

	//测试
	void setToDead() {
		m_life = 0;
	}
	void print() {
		cout << "life:" << m_life << ",attack:" << m_attack << ",magic:" << m_magic << endl;
	}

private:
	int m_life;
	int m_attack;
	int m_magic;
};

class FCareTaker {
public:
	void setMemento(FMememento* memento) {
		m_memento = memento;
	}
	FMememento* getMemento() {
		return m_memento;
	}
private:
	FMememento* m_memento;
};

int main() {
	unique_ptr<Fighter> fighter = make_unique<Fighter>(100, 100, 100);
	unique_ptr<FCareTaker> careTaker = make_unique<FCareTaker>();
	careTaker->setMemento(fighter->createMemento());
	fighter->print();

	fighter->setToDead();
	fighter->print();

	fighter->restoreMemento(careTaker->getMemento());
	fighter->print();

}
;