设计模式-第十四章-备忘录模式(c++)
作者:互联网
一、UML图
二、包含的角色
Memento类, 是原发器状态快照的值对象 (value object)。 通常做法是将备忘录设为不可变的, 并通过构造函数一次性传递数据。
Originator类可以生成自身状态的快照, 也可以在需要时通过快照恢复自身状态。
Caretaker类, 仅知道 “何时” 和 “为何” 捕捉原发器的状态, 以及何时恢复状态。通过保存备忘录栈来记录原发器的历史状态。 当原发器需要回溯历史状态时, 负责人将从栈中获取最顶部的备忘录, 并将其传递给原发器的恢复 (restoration) 方法。
三、特点
备忘录模式是一种行为设计模式, 允许在不暴露对象实现细节的情况下保存和恢复对象之前的状态。
允许你复制对象中的全部状态 (包括私有成员变量), 并将其独立于对象进行保存。 尽管大部分人因为 “撤销” 这个用例才记得该模式, 但其实它在处理事务 (比如需要在出现错误时回滚一个操作) 的过程中也必不可少。让对象自行负责创建其状态的快照。 任何其他对象都不能读取快照, 这有效地保障了数据的安全性。
四、代码实现
Memento类
#pragma once
#include <chrono>
#include <ctime>
#include <iomanip>
#include <sstream>
#include <string>
/**
* The Memento interface provides a way to retrieve the memento's metadata, such
* as creation date or name. However, it doesn't expose the Originator's state.
*/
class Memento
{
public:
Memento(std::string state) : state_(state)
{
this->date_ = time_in_HH_MM_SS_MMM();
}
virtual ~Memento() {}
public:
std::string state() const
{
return this->state_;
}
std::string date() const
{
return this->date_;
}
protected:
std::string time_in_HH_MM_SS_MMM()
{
using namespace std::chrono;
// get current time
auto now = system_clock::now();
// get number of milliseconds for the current second
// (remainder after division into seconds)
auto ms = duration_cast<milliseconds>(now.time_since_epoch()) % 1000;
// convert to std::time_t in order to convert to std::tm (broken time)
auto timer = system_clock::to_time_t(now);
// convert to broken time
std::tm bt = *std::localtime(&timer);
std::ostringstream oss;
oss << std::put_time(&bt, "%H:%M:%S"); // HH:MM:SS
oss << '.' << std::setfill('0') << std::setw(5) << ms.count();
return oss.str();
}
std::string state_;
std::string date_;
};
Originator类
#pragma once
#include "Memento.h"
#include <iostream>
#include <random>
class Originator
{
/**
* @var string For the sake of simplicity, the originator's state is stored
* inside a single variable.
*/
private:
std::string state_;
int index_;
public:
Originator(std::string state) : state_(state)
{
index_=1;
std::cout << "Originator: My initial state is: " << this->state_ << "\n";
}
/**
* Saves the current state inside a memento.
*/
Memento *Save()
{
return new Memento(this->state_);
}
/**
* Restores the Originator's state from a memento object.
*/
void Restore(Memento *memento)
{
this->state_ = memento->state();
std::cout << "Originator Restore: My state has changed to: " << this->state_ << " : "<< memento->date() << "\n";
}
void ChangeState()
{
this->state_ = std::string("状态"+ std::to_string(index_++));
std::cout << "Originator ChangeState: My state has changed to: " << this->state_ << "\n";
}
};
Caretaker类
#pragma once
#include "Originator.h"
#include <iostream>
#include <random>
/**
* The Caretaker doesn't depend on the Concrete Memento class. Therefore, it
* doesn't have access to the originator's state, stored inside the memento. It
* works with all mementos via the base Memento interface.
*/
class Caretaker
{
public:
Caretaker(Originator *originator) : originator_(originator)
{
this->originator_ = originator;
}
~Caretaker()
{
for (auto it = mementos_.begin(); it != mementos_.end(); ++it)
{
if ((*it) != nullptr)
{
delete (*it);
}
}
}
void Backup()
{
std::cout << "\nCaretaker: Saving Originator's state...\n";
this->mementos_.push_back(this->originator_->Save());
}
void Undo()
{
if (!this->mementos_.size())
{
return;
}
Memento *memento = this->mementos_.back();
this->mementos_.pop_back();
std::cout << "Caretaker: Restoring state to: " << memento->date() << "\n";
try
{
this->originator_->Restore(memento);
}
catch (...)
{
this->Undo();
}
}
void ShowHistory() const
{
std::cout << "Caretaker: Here's the list of mementos:\n";
for (Memento *memento : this->mementos_)
{
std::cout << memento->state() << " : "<<memento->date() << "\n";
}
}
private:
std::vector<Memento *> mementos_;
Originator *originator_;
};
main
#include "Caretaker.h"
#include "Originator.h"
#include <unistd.h>
int main()
{
Originator *originator = new Originator("状态0");
Caretaker *caretaker = new Caretaker(originator);
caretaker->Backup(); // 保存状态
sleep(1);
originator->ChangeState();
caretaker->Backup(); // 保存状态
sleep(1);
originator->ChangeState();
caretaker->Backup(); // 保存状态
caretaker->ShowHistory();
printf("\nClient: Now, let's rollback!\n\n");
caretaker->Undo();
printf("\nClient: Once more!\n\n");
caretaker->Undo();
printf("\nClient: Once more!\n\n");
caretaker->Undo();
return 0;
}
标签:std,originator,include,c++,state,Originator,第十四章,设计模式,Memento 来源: https://blog.csdn.net/fanrongwoaini/article/details/83004778