备忘录模式

简介: 备忘录模式(Memento Pattern)是一种行为设计模式,用于在不暴露对象内部状态的情况下,捕获并存储对象的当前状态,以便日后可以将对象恢复到存储的状态。该模式主要由三个角色组成:发起人(Originator)、备忘录(Memento)和管理者(Caretaker)。发起人负责创建和恢复备忘录,备忘录存储发起人的状态,管理者则负责保存备忘录但不修改其内容。备忘录模式常用于支持撤销/恢复操作,如文本编辑器、游戏状态管理等。优点包括封装性好、支持撤销/恢复操作,但缺点是可能消耗较多资源。

备忘录模式

概念

备忘录模式(Memento Pattern)是一种行为设计模式,用于在不暴露对象内部状态的情况下,捕获并存储对象的当前状态,以便日后可以将对象恢复到存储的状态。备忘录模式可以有效地实现撤销/恢复操作。


组件和职责

组件 描述
Originator(发起人) 定义一个创建备忘录和恢复备忘录的接口,记录并还原对象状态。
Memento(备忘录) 存储发起人的状态,提供发起人访问但对其他对象不可见,确保封装性。
Caretaker(管理者) 负责保存备忘录但不修改它的内容,通常通过栈或列表记录状态以支持多步撤销或恢复操作。

使用场景

使用场景 描述
需要保存对象状态 需要将对象状态保存到外部存储但不暴露内部实现细节。
支持撤销/恢复功能 允许用户撤销某些操作并恢复到之前的状态,如文本编辑器、游戏状态管理等。
复杂对象状态管理 状态的保存和恢复需要被系统有效管理,避免直接操作对象的内部实现。

优点与缺点

优点 缺点
封装性:保持对象的封装性,外部无法访问内部状态。 存储开销:保存多个备忘录可能消耗较多资源。
撤销/恢复:支持轻松撤销和恢复操作。 实现复杂性:设计和管理备忘录存储结构复杂。
操作简单:发起人通过接口即可实现状态保存与恢复。 过多备忘录:历史记录过多可能影响性能。

与其他模式的比较

特性 备忘录模式 命令模式
主要作用 保存和恢复对象状态 将操作封装为对象,支持撤销和记录。
状态管理 专注于对象状态的存储和恢复 通过执行命令的撤销方法管理状态。
操作与状态的分离 将状态存储和操作逻辑分开 将操作封装为命令对象,与状态解耦。

实现代码

C++ 实现

#include <iostream>
#include <string>
#include <vector>

// Memento
class Memento {
private:
   std::string state;

public:
   Memento(const std::string& s) : state(s) {}
   std::string getState() const { return state; }
};

// Originator
class Originator {
private:
   std::string state;

public:
   void setState(const std::string& s) { state = s; }
   std::string getState() const { return state; }

   Memento saveToMemento() { return Memento(state); }
   void restoreFromMemento(const Memento& memento) { state = memento.getState(); }
};

// Caretaker
class Caretaker {
private:
   std::vector<Memento> mementoList;

public:
   void addMemento(const Memento& memento) { mementoList.push_back(memento); }
   Memento getMemento(size_t index) { return mementoList.at(index); }
};

// Example
int main() {
   Originator originator;
   Caretaker caretaker;

   originator.setState("State1");
   caretaker.addMemento(originator.saveToMemento());

   originator.setState("State2");
   caretaker.addMemento(originator.saveToMemento());

   originator.setState("State3");

   std::cout << "Current State: " << originator.getState() << std::endl;

   originator.restoreFromMemento(caretaker.getMemento(0));
   std::cout << "Restored to: " << originator.getState() << std::endl;

   return 0;
}


C# 实现

using System;
using System.Collections.Generic;

// Memento
class Memento {
   public string State { get; private set; }
   public Memento(string state) {
       State = state;
   }
}

// Originator
class Originator {
   public string State { get; set; }

   public Memento SaveToMemento() {
       return new Memento(State);
   }

   public void RestoreFromMemento(Memento memento) {
       State = memento.State;
   }
}

// Caretaker
class Caretaker {
   private List<Memento> _mementos = new List<Memento>();

   public void AddMemento(Memento memento) {
       _mementos.Add(memento);
   }

   public Memento GetMemento(int index) {
       return _mementos[index];
   }
}

// Example
class Program {
   static void Main() {
       Originator originator = new Originator();
       Caretaker caretaker = new Caretaker();

       originator.State = "State1";
       caretaker.AddMemento(originator.SaveToMemento());

       originator.State = "State2";
       caretaker.AddMemento(originator.SaveToMemento());

       originator.State = "State3";

       Console.WriteLine($"Current State: {originator.State}");

       originator.RestoreFromMemento(caretaker.GetMemento(0));
       Console.WriteLine($"Restored to: {originator.State}");
   }
}


类图

image.png

相关文章
|
11月前
|
设计模式 IDE 数据可视化
UML中类图的介绍与使用
类图是 UML 中用于展示系统静态结构的重要工具,包括类、接口及其关系。类图有助于系统可视化、团队沟通、发现设计问题、文档化系统和辅助开发工具。类图的三大元素是类、接口和关系,其中关系又细分为关联、聚合、组合、继承、实现和依赖。类图在设计模式学习和实际开发中非常重要,许多现代 IDE 都支持从类图生成代码或从代码生成类图。
|
11月前
|
存储 安全 编译器
第二问:C++中const用法详解
`const` 是 C++ 中用于定义常量的关键字,主要作用是防止值被修改。它可以修饰变量、指针、函数参数、返回值、类成员等,确保数据的不可变性。`const` 的常见用法包括:
|
11月前
|
Cloud Native
邀您参加云原生高可用技术沙龙丨云上高可用体系构建:从理论到实践
云原生高可用技术专场,邀您从理论到实践一起交流,探索云上高可用体系构建!
197 81
|
11月前
|
人工智能 Serverless API
10 分钟打造你的专属 AI 客服
在这个数字化时代,提供卓越的客户服务已成为企业脱颖而出的关键。为了满足这一需求,越来越多的企业开始探索人工智能(AI)助手的应用,以实现全天候(7x24)的客户咨询响应,全面提升用户体验和业务竞争力。本解决方案通过函数计算FC 和大模型服务平台百炼,为您提供一个高效便捷构建 AI 助手思路。
867 43
|
11月前
|
XML 设计模式 JSON
模板方法模式(Template Method Pattern)
模板方法模式是一种行为型设计模式,定义一个操作中的算法骨架,将某些步骤的实现延迟到子类。子类可以在不改变算法结构的情况下重新定义算法的某些步骤。适用于多个类有相似操作流程且部分步骤需要定制的场景。优点包括高复用性、扩展性强和清晰明确;缺点是灵活性降低和可能引入性能开销。示例包括文件解析和策略模式的对比。
模板方法模式(Template Method Pattern)
|
11月前
|
存储 设计模式 算法
命令模式(Command Pattern)
命令模式是一种行为型设计模式,将请求封装为对象,实现参数化请求、支持撤销操作和记录日志。适用于需要解耦发送者和接收者的场景,如智能家居系统中的遥控器控制电灯开关并支持撤销功能。优点包括解耦、支持撤销与恢复操作,但过度使用会增加系统复杂度。
|
11月前
|
存储 设计模式 C#
享元模式(Flyweight Pattern)
享元模式是一种结构型设计模式,通过共享对象来减少内存使用。它将对象分为共享和非共享部分,通过享元工厂管理和复用共享对象,适用于大量相似对象的场景,能显著节省内存并提高性能。典型应用包括文本编辑器中的字符样式和图形系统中的图形属性。
|
11月前
|
设计模式 C# C++
责任链模式(Chain of Responsibility Pattern)
责任链模式是一种行为型设计模式,允许多个对象按顺序处理请求,直到某个对象处理为止。适用于多个对象可能处理同一请求的场景,如请假审批流程。优点是灵活性高、降低耦合,但责任链过长可能影响性能。
|
11月前
|
设计模式 数据库 C#
外观模式(Facade Pattern)
外观模式(Facade Pattern)是一种结构型设计模式,为子系统中的一组接口提供一个一致的接口。它通过一个高层接口简化子系统的复杂性,使客户端更容易使用。外观模式的核心角色包括外观(Facade)和子系统(Subsystems),主要优点是降低复杂性和松耦合,适用于简化接口、分层设计和遗留代码集成等场景。
|
11月前
|
设计模式 API C#
桥接模式(Bridge Pattern)
桥接模式是一种结构型设计模式,通过将抽象部分与实现部分分离,使它们可以独立变化,从而提高系统的灵活性和扩展性。主要角色包括抽象化、扩展抽象化、实现和具体实现。适用于多变化维度的系统,如跨平台开发、图形系统等。优点是分离抽象与实现,减少子类数量;缺点是增加了复杂性和理解难度。