当前位置: 首页 > news >正文

106、23种设计模式之备忘录模式(15/23)

一、定义

备忘录模式(Memento Pattern)是一种行为型设计模式,它允许在不破坏对象封装性的前提下,捕获并外部化对象的内部状态,以便后续恢复到该状态。其核心思想是通过一个“备忘录”对象存储原发器(Originator)的状态,并由管理者(Caretaker)负责保存和传递备忘录,实现状态的撤销与恢复。

二、优缺点

1.优点:

  • 封装性保护:原发器的内部状态对外部隐藏,仅通过备忘录接口访问,避免直接暴露实现细节。
  • 撤销/重做支持:适合需要回退到历史状态的场景(如文本编辑器的Ctrl+Z)。
  • 灵活性:备忘录可存储在内存、数据库或文件中,适应不同需求。

2.缺点:

  • 内存消耗:保存大量备忘录或复杂状态时,内存占用可能显著增加。
  • 系统复杂度:简单场景下引入备忘录可能增加代码复杂度。
  • 线程安全:多线程环境下需额外处理备忘录的创建、存储和恢复的同步问题。

三、应用场景

  • 需要撤销/重做功能的系统:如Word文档编辑、图形设计软件。
  • 游戏存档与恢复:保存角色状态、关卡进度。
  • 复杂对象状态管理:避免直接暴露对象内部属性,同时支持状态回滚。
  • 多级历史记录:如浏览器后退功能,需维护多个历史状态。

四、C# 示例代码

以下是一个完整的C#实现,模拟游戏角色状态保存与恢复:

using System;
using System.Collections.Generic;// 备忘录类:存储角色状态
public class CharacterMemento
{public int Level { get; }public int Health { get; }public string CurrentWeapon { get; }public Position Position { get; }public CharacterMemento(int level, int health, string weapon, Position position){Level = level;Health = health;CurrentWeapon = weapon;Position = position;}
}// 位置类
public class Position
{public int X { get; set; }public int Y { get; set; }public Position(int x, int y){X = x;Y = y;}
}// 原发器类:游戏角色
public class GameCharacter
{public string Name { get; set; }public int Level { get; set; }public int Health { get; set; }public string CurrentWeapon { get; set; }public Position Position { get; set; }// 创建备忘录(存档)public CharacterMemento Save(){return new CharacterMemento(Level, Health, CurrentWeapon, Position);}// 从备忘录恢复(读档)public void Restore(CharacterMemento memento){Level = memento.Level;Health = memento.Health;CurrentWeapon = memento.CurrentWeapon;Position = memento.Position;Console.WriteLine($"角色已恢复到: 等级{Level}, 生命{Health}, 武器{CurrentWeapon}, 位置({Position.X},{Position.Y})");}// 显示当前状态public void Display(){Console.WriteLine($"当前状态: {Name} 等级{Level}, 生命{Health}, 武器{CurrentWeapon}, 位置({Position.X},{Position.Y})");}
}// 管理者类:保存备忘录
public class SaveGameManager
{private Dictionary<string, CharacterMemento> _saves = new Dictionary<string, CharacterMemento>();public void AddSave(string saveName, CharacterMemento memento){_saves.Add(saveName, memento);Console.WriteLine($"游戏已存档: {saveName}");}public CharacterMemento GetSave(string saveName){if (_saves.TryGetValue(saveName, out var memento)){return memento;}throw new KeyNotFoundException($"未找到存档: {saveName}");}
}// 客户端代码
class Program
{static void Main(){// 初始化角色var character = new GameCharacter{Name = "勇士",Level = 1,Health = 100,CurrentWeapon = "铁剑",Position = new Position(0, 0)};// 创建管理者var manager = new SaveGameManager();// 显示初始状态character.Display();// 存档var memento = character.Save();manager.AddSave("初始存档", memento);// 修改状态(模拟游戏过程)character.Level = 5;character.Health = 80;character.CurrentWeapon = "火焰剑";character.Position = new Position(10, 20);Console.WriteLine("\n游戏进行中,角色状态变化:");character.Display();// 恢复存档Console.WriteLine("\n恢复初始存档:");character.Restore(manager.GetSave("初始存档"));character.Display();}
}

输出结果:

当前状态: 勇士 等级1, 生命100, 武器铁剑, 位置(0,0)
游戏已存档: 初始存档游戏进行中,角色状态变化:
当前状态: 勇士 等级5, 生命80, 武器火焰剑, 位置(10,20)恢复初始存档:
角色已恢复到: 等级1, 生命100, 武器铁剑, 位置(0,0)
当前状态: 勇士 等级1, 生命100, 武器铁剑, 位置(0,0)

五、关键点总结

1.角色分离:

  • 原发器(Originator):负责创建和恢复备忘录。
  • 备忘录(Memento):存储状态,提供窄接口(仅原发器可访问完整数据)。
  • 管理者(Caretaker):保存备忘录,不操作其内容。

2.封装性:备忘录通过窄接口限制外部访问,确保原发器状态安全。

3.内存管理:需权衡备忘录数量与内存消耗,避免过度保存。

4.扩展性:支持多级撤销(如用栈结构存储备忘录)或持久化存储(如数据库)。

5.适用场景:优先在需要状态回滚且直接访问对象属性会破坏封装时使用。

在这里插入图片描述

http://www.dtcms.com/a/452813.html

相关文章:

  • LangChain部署rag Part3olmOCR与MinerU工具(赋范大模型社区公开课听课笔记)
  • C++进阶:使用普通函数重载算数运算符
  • 从内核调优到集群部署:基于Linux环境下KingbaseES数据库安装指南
  • Micro850 控制器深度解析:硬件特性与 I/O 接线核心(罗克韦尔2)
  • Python oct() 函数
  • (一) 机器学习之深度神经网络
  • C语言指针全面解析:从内存管理到高级应用
  • 南通网站建设推广专家建站教程的优点
  • Spring Boot整合Apache Shiro权限认证框架(应用篇)
  • 杰理AC632N---RTC应用问题
  • 网站免费软件下载阳江人社局官网招聘
  • 第二十三章:解析天书,诠释法则——Interpreter的解释艺术
  • 论文阅读-FoundationStereo
  • bug日记
  • 大数据集群环境搭建(Ubantu)
  • 深入浅出 HarmonyOS 应用开发:ArkTS 语法精要与实践
  • 用 Python+OpenCV 实现实时文档扫描:从摄像头捕捉到透视矫正全流程
  • 普陀做网站公司任丘市建设局网站
  • 前端框架篇——VueReact篇
  • R语言从入门到精通Day4之【数据结构】
  • JavaScript快速入门_javascript入门教程
  • 有几家做网站的公司易贝跨境电商平台
  • 基于websocket的多用户网页五子棋(六)
  • 月光与饼:Python 爱情月饼可视化
  • 【C++】STL有序关联容器的双生花:set/multiset 和 map/multimap 使用指南
  • 迷你论坛项目
  • 【C++STL】一文掌握 String 核心接口:从基础到实用!
  • 长沙宁乡建设网站网站本地环境搭建
  • 从以太网到多个 CAN 网络的网关
  • 网站做弹窗怀化职院网站