备忘录模式-C++实现

备忘录是一种行为型设计模式,它允许在不破坏封装性的前提下捕获和恢复一个对象的内部状态。它将对象的内部状态保存到备忘录对象中,并在需要的时候从备忘录中取出恢复状态,实现了状态的保存和恢复。

备忘录有以下三个角色:

1、发起人(Originator):是需要备份和恢复状态的对象。它能够创建备忘录对象,并可以从备忘录中恢复状态。

2、备忘录(Memento):用于存储发起人对象的状态,备忘录可以保持任意类型的状态数据,但不对外公开。

3、管理者(Caretaker):负责管理者对象,包括保存和提供备忘录,它通常只保存最后一次备忘录对象。

工作流程:

1、发起人创建备忘录对象,并将自身状态存储到备忘录中。

2、发起人可以在任何时候从备忘录中恢复状态,将备忘录中保存的状态数据还原到自身。

举例:

假设我们现在有一组int类型的数据,用户在界面上修改了这组数据的值,但最后用户不想保存。

#include 
#include 
#include 

// 备忘录对象
class Memento
{
public:

	Memento(const std::vector<int>& _data)
		: data_(_data)
	{}

	std::vector<int> GetMemento()
	{
		return data_;
	}

private:

	std::vector<int> data_;
};

// 发起人
class Originator
{
public:

	void SetData(const std::vector<int>& _data)
	{
		data_ = _data;
	}

	// 创建备忘录
	std::shared_ptr<Memento> CreateMemento()
	{
		return std::make_shared<Memento>(data_);
	}

	// 恢复状态
	void RestoreMemento(std::shared_ptr<Memento> _memento)
	{
		data_ = _memento->GetMemento();
	}

	// 输出数据
	void PrintData()
	{
		for (int i = 0; i < data_.size(); i++)
			std::cout << data_[i] << " ";

		std::cout << std::endl;
	}

private:

	std::vector<int> data_;
};

// 管理者对象
class Caretaker
{
public:

	void AddMemento(std::shared_ptr<Memento> _memento)
	{
		history_.emplace_back(_memento);
	}

	std::shared_ptr<Memento> GetMemento(const int& idx)
	{
		if (history_.size() <= idx)
			return nullptr;
		
		std::shared_ptr<Memento> temp = history_[idx];
		history_.erase(history_.begin() + idx);

		return temp;
	}

private:
	std::vector<std::shared_ptr<Memento>> history_;
};

代码示例中,我们首先创建了一个备忘录类,实现的方法有获取该备忘录对象的状态,这个状态是在构造的时候传进去并保存下来。然后创建了一个发起人类,实现了设置状态、创建备忘录对象、恢复状态、输出状态的方法。最后创建了一个备忘录管理者对象,用于管理所有发起人创建的备忘录对象,实现的方法有添加备忘录对象、从备忘录管理列表里取出一个对象。

测试:

void TestMemento()
{
	// 创建初始数据
	std::vector<int> data = { 1, 2, 3, 4, 5 };

	// 创建发起人
	std::shared_ptr<Originator> originator = std::make_shared<Originator>();
	// 创建备忘录管理者
	std::shared_ptr<Caretaker> careTaker = std::make_shared<Caretaker>();

	originator->SetData(data);
	std::shared_ptr<Memento> memento = originator->CreateMemento();

	// 存到备忘录管理者
	careTaker->AddMemento(memento);

	originator->PrintData();

	std::cout << "-----------------------" << std::endl;

	// 用户修改后的数据为
	std::vector<int> data1 = { 1,3,4,2,1 };
	originator->SetData(data1);

	// 创建备忘录并保存状态
	std::shared_ptr<Memento> memento1 = originator->CreateMemento();
	careTaker->AddMemento(memento1);

	originator->PrintData();
	std::cout << "-----------------------" << std::endl;

	// 用户不想保存修改后的数据,我们来恢复
	originator->RestoreMemento(careTaker->GetMemento(0));

	originator->PrintData();

}

测试代码示例中,我们先创建了一组数据(1,2,3,4,5)作为我们的初始数据,并把这个数据保存到备忘录中。然后模拟用户修改数据为(1,3,4,2,1),也把这个数据保存到备忘录中。最后用户不想保存修改后的数据,那我们就需要把数据恢复到初始状态。

输出:

1 2 3 4 5
-----------------------
1 3 4 2 1
-----------------------
1 2 3 4 5

备忘录模式遵循以下原则:

1、单一职责原则:备忘录对象负责存储对象的状态、发起人负责创建备忘录和恢复对象状态、管理者类负责管理备忘录对象。每个类有明确的责任。

2、开放封闭原则:备忘录模式允许发起人随意的增加备忘录和恢复状态,无需修改现有的代码,符合开放封闭原则。

优点:

1、状态保存和恢复:备忘录模式可以通过在发起人类和备忘录类之间引入备忘录对象,实现对象状态的保存和恢复。这样可以将对象的状态从发起人类中分离出来,以实现更好的封装性和隔离性。

2、简化发起人类:因为备忘录模式可以减轻发起人类的负担,因为它把发起人类的状态保存和恢复委托给了备忘录类和备忘录管理者类,这样使得发起人类更加简单并且易于维护。

3、支持多次恢复:备忘录模式允许备忘录管理者类中添加多个状态,这样可以支持多次恢复操作,这使得系统具有撤销和重做的能力。

缺点:

1、多个备忘录对象的管理:如果需要管理大量的备忘录对象,可能会增加备忘录管理者的复杂性。

2、内存消耗问题:如果要保存的对象状态数量很大或者状态很大时,需要占用更多的内存。

3、状态一致性问题:因为备忘录模式将发起人的状态分散开来,如果发起人的其他操作依赖于状态时,需要保持一致性。

你可能感兴趣的:(设计模式,c++,备忘录模式,算法)