我们来用Unity的形式讲一下备忘录模式
你可以把备忘录模式想象成游戏中的“存档”和“读档”功能。 它的核心思想是: 再不破坏对象封装性的前提下, 捕获一个对象的内部状态, 并在该对象之外保存这个状态, 以便日后可以将对象恢复到原先保存的状态.
举个具体场景: 游戏角色状态保存与恢复
假设你正在开发一款RPG游戏, 玩家控制角色有以下状态:
- 生命值(Health)
- 魔法值(Mana)
- 位置(Position)
- 当前装备(Equipment)
当玩家进入一个危险的地牢前, 他可能会想”存档”. 如果在地牢里不幸死亡, 它可以”读档”回到进入地牢前的状态, 而不是从头开始.
在这个场景中, 我们可以使用备忘录模式来实现这个功能:
- 角色(
Player)是哪个需要被”存档”的对象, 它知道如何创建一个包含自己当前状态的”备忘录”, 也知道如何从”备忘录”中恢复自己的状态.
- 游戏存档(
GameSave)就是”备忘录”, 它是一个简单的数据容器, 用来存储角色状态(生命值\魔法值等). 它不包含任何游戏逻辑.
- 存档管理器(
SaveManager)负责管理所有的”备忘录”. 它可以保存新的存档, 也可以根据需要取出一个旧的存档共角色恢复.
备忘录模式的核心角色
- 是谁? 在我们的例子中是
Player脚本 - 作用是什么?
- 创建备忘录: 它可以在某个时刻, 将自己的内部状态(如生命值\位置)打包成一个备忘录对象
- 恢复状态: 它可以从一个备忘录对象中, 恢复自己的内部状态
- 关键特点: 它拥有自己的状态, 但它不负责存储这些状态的历史, 这个工作交给了负责人.
- 是谁? 在我们的例子中是
GameSave类 - 作用是什么?
- 存储状态: 它是一个用来存储发起人内部状态的数据容器
- 保护状态: 它应该只允许发起人访问它的内部数据. 其他对象不应该能够读取或修改它
- 关键特点: 它通常是一个简单的\可序列化的类, 只包含数据字段和相应的gettrt/setter方法(或者在某些实现中, setter 是私有的, 只能由发起人调用).
- 是谁? 在我们例子中是 SaveManager 脚本
- 作用是什么?
- 管理备忘录: 它负责保存一系列备忘录对象, 可以把它想象成一个”存档列表”
- 提供访问: 当需要时, 它可以将一个特定的备忘录对象返回给发起人, 以便发起人进行状态恢复.
- 关键特点: 它不知道备忘录对象内部存储的具体细节. 它只负责”保管”备忘录, 而不”使用”它. 它与备忘录之间是一种聚合关系.
代码实现步骤
- 定义备忘录(Memento) -
GameSave.cs
这是一个纯数据类, 用于存储角色的状态. 为了模式”只有发起人能访问”, 我们可以把 SetState 方法设为 internal 或通过狗在函数来初始化. 在C#中, 一个常见的作法是把备忘录类嵌套在发起人内部, 或者使用访问修饰符来控制. 这里我们为了清晰, 采用独立的类, 并通过构造一次性设置所有状态.
- 定义发起人(Originator) -
Player.cs
这个类包含了角色当前状态和行为. 它负责创建和恢复备忘录.
- 定义负责人(Caretaker) -
SaveManager.cs
这个类负责管理所有的游戏存档
- 客户端使用 -
GameManager.cs
这是一个简单的游戏管理器, 用于演示整个流程
在 Unity 编辑器中配置
- 创建一个玩家对象(PLayer), 并添加 Player.cs 脚本
- 创建一个空对象作为
GameManager, 并添加GameManager.cs脚本.
- 在场景中创建另一个空对象, 命名为
SaveManager并添加,SaveManager.cs脚本
- 在
GameManager的 Inspector 面板中, 将Player对象和SaveManager对象拖到对应字段上.
- 运行游戏,在游戏视图中按以下按键进行测试:
- S:创建一个名为 "
BeforeDungeon" 的存档。 - D:让玩家受到伤害。
- F:让玩家施放法术,消耗魔法。
- L:加载 "
BeforeDungeon" 存档,玩家的生命值、魔法值和位置将恢复到存档时的状态。
备忘录模式的核心优势
- 状态保存与恢复: 这是最直接的好处, 允许对象在不同时间点之间切换状态, 非常适合实现”撤销/重做”或”存档/读档”功能.
- 封装性: 发起人(
Player)的内部状态被封装在备忘录(GameSave)中, 并且只有发起人自己能够创建和恢复这个状态. 负责人(SaveManager)和其它对象无法访问或修改发起人内部的细节, 复合”封装变化”的原则.
- 简化发起人: 发起人不需要自己管理和维护状态的历史记录, 这个责任被移交给了负责人, 使得发起人代码更加简洁.
在Unity中的其他应用场景
- 编辑器工具: 自定义编辑器窗口中, 对复杂配置的操作进行”撤销/重做”.
- 动画系统: 保存和恢复动画状态机的某个特定状态
- AI 行为: 在某些决策点保存AI的当前状态, 以便在特定条件下会输到之前的决策.
总结: 备忘录模式通过将对象状态的保存和恢复责任分离, 实现了对象状态的灵活管理, 同时保持了对象的封装性. 它就像一个可靠的”时光机”, 让对象可以在不同的状态之间自由穿梭