设计模式(C++)-行为型模式-备忘录模式

设计模式(C++)-行为型模式-备忘录模式

一、备忘录模式概述

备忘录模式是一种行为型模式,允许在不破坏封装性的前提下,捕获并保存一个对象的内部状态,以便以后可以恢复到这个状态。
核心思想

cpp 复制代码
三个关键角色:
1. Originator(原发器):需要保存状态的对象
2. Memento(备忘录):存储Originator内部状态的对象
3. Caretaker(负责人):负责保存和恢复备忘录,但不操作备忘录内容

二、备忘录模式UML类图

备忘录场景

备忘录模式的典型应用场景包括:

撤销操作:在编辑器中,用户可能希望撤销最近的几次操作。

游戏存档:在游戏过程中,玩家可能希望保存当前进度,以便之后可以继续游戏。

事务处理:在数据库事务中,如果事务失败,需要恢复到事务之前的状态。

三、代码实现

cpp 复制代码
//memento.h
#pragma once
/*
备忘录模式(Memento Pattern)
是一种软件设计模式,属于行为型模式。
它主要用于保存一个对象的某个状态,以便在需要时可以恢复到这个状态。
备忘录模式通常用于实现撤销功能,或者在某些情况下,实现对象的快照功能。
备忘录模式涉及三个角色:
Originator(发起人):创建一个备忘录Memento,用以记录当前时刻的内部状态,并可以使用Memento恢复内部状态。
Memento(备忘录):负责存储Originator的内部状态,并可以防止外部直接修改这个状态。
Caretaker(管理者):负责保存好Memento,不能对Memento的内容进行操作或检查,只能进行保存或丢弃。
备忘录模式的典型应用场景包括:
撤销操作:在编辑器中,用户可能希望撤销最近的几次操作。
游戏存档:在游戏过程中,玩家可能希望保存当前进度,以便之后可以继续游戏。
事务处理:在数据库事务中,如果事务失败,需要恢复到事务之前的状态。
*/
#include <vector>
#include <memory>
#include <iostream>
class Memento;
//发起人 类负责创建备忘录,并根据备忘录恢复状态
class  {
public:
	Originator(int state) :state_(state) {}
	//创建备忘录
	std::shared_ptr<Memento> saveStateToMemento();
	//恢复状态
	void getStateFromMemento(std::shared_ptr<Memento>memento);

	//打印当前状态
	void printState();
	//用于改变状态的方法
	void setState(int newState);
	//获取当前状态
	int  getState()const;
private:
	int state_;
};

//备忘录类,负责存储发起人的内部状态
class Memento {
public:
	explicit Memento(int state) : state_(state) {}
	int getState();
private:
	int state_;
};

//管理者类,负责保存备忘录
class Caretaker {
public:
	//保存备忘录
	void add(std::shared_ptr<Memento>memonto);
	//根据索引获取备忘录
	std::shared_ptr<Memento> get(int index);
private:
	std::vector<std::shared_ptr<Memento>> mementoList_;
};

void testMemento();
//memento.cc
#include "memento.h"
std::shared_ptr<Memento> Originator::saveStateToMemento() {
	return std::make_shared<Memento>(state_);
}
void Originator::getStateFromMemento(std::shared_ptr<Memento>memento) {
	state_ = memento->getState();
}
void Originator::printState() {
	std::cout << "Current state: " << state_ << std::endl;
}
void Originator::setState(int newState) {
	state_ = newState;
}
int Originator::getState()const {
	return state_;
}
int Memento::getState() {
	return state_;
}
void Caretaker::add(std::shared_ptr<Memento>memonto) {
	mementoList_.push_back(memonto);
}
std::shared_ptr<Memento> Caretaker::get(int index) {
	return mementoList_.at(index);
}
void testMemento() {
	std::cout << "=================memento start===============" << std::endl;
	//创建发起人对象,初始状态为10
	Originator* originator = new Originator(10);
	Caretaker caretaker; //创建管理者对象

	//保存状态
	originator->printState();
	caretaker.add(originator->saveStateToMemento());

	//改变状态
	originator->setState(20);
	originator->printState();

	//恢复状态
	originator->getStateFromMemento(caretaker.get(0));
	originator->printState();
   
	//释放发起人对象
	delete originator;
	originator = nullptr;
	std::cout << "=================memento end===============" << std::endl;
}

四、优缺点总结

优点:

  • 封装性好:不暴露对象内部状态
  • 可恢复性:支持状态回滚
  • 简化原发器:状态保存逻辑分离
  • 支持撤销/重做:适合实现编辑器功能

缺点:

  • 内存消耗:大量备忘录可能占用过多内存
  • 性能考虑:状态序列化/反序列化开销
  • 深拷贝问题:复杂对象的深度复制
  • 线程安全:多线程环境下的状态管理
相关推荐
wljy11 天前
二、进制状态转换
linux·运维·服务器·c语言·c++
云泽8081 天前
笔试算法 -位运算篇(二):从唯一字符到消失数字
c++·算法·位运算
繁华落尽,倾城殇?1 天前
[C++11] : atomic,nullptr,default/delete,enum class
开发语言·c++·c++11·nullptr·atomic·enum class·default/delete
代码村新手1 天前
C++-二叉搜索树
开发语言·c++
智者知已应修善业1 天前
【51单片机8位数码管动态显示日期小数点风格】2023-11-13
c++·经验分享·笔记·算法·51单片机
智者知已应修善业1 天前
【51单片机有三个LED 分别第一个灯闪三下 再到第二个灯又闪三下 再到第三个灯又闪三下 就这样循环程序】2023-11-16
c++·经验分享·笔记·算法·51单片机
Doris_20231 天前
代码格式化 使用oxfmt
设计模式·架构·前端框架
Doris_20231 天前
说一说ESLint+Prettier生效的原理
前端·设计模式·架构
Pomelooooo1 天前
把 git commit 这件事,彻底交给 AI ——一个工程化 /git-commit 命令的设计与落地
设计模式
玖釉-1 天前
二叉树展开为链表:从先序遍历到原地指针重排
c++·windows·算法·leetcode·链表