设计模式——备忘录模式

备忘录模式 (Memento Pattern)

什么是备忘录模式?

备忘录模式是一种行为型设计模式,它允许你在不违反封装原则的前提下保存和恢复对象的内部状态

简单来说:备忘录模式就是"存档",可以保存对象的状态,之后可以恢复。

生活中的例子

想象一下:

  • 游戏存档:保存游戏进度,之后可以恢复
  • 文档撤销:撤销操作,恢复到之前的状态
  • 版本控制:Git提交,可以恢复到之前的版本

为什么需要备忘录模式?

传统方式的问题

java 复制代码
// 直接保存状态
Object state = object.getState();
object.setState(state);

问题

  1. 破坏封装:需要暴露对象的内部状态
  2. 无法撤销:无法撤销到之前的状态
  3. 难以管理:难以管理多个状态

备忘录模式的优势

java 复制代码
// 使用备忘录
Memento memento = object.save();
object.restore(memento);

优势

  1. 保持封装:不暴露对象的内部状态
  2. 可以撤销:可以撤销到之前的状态
  3. 易于管理:易于管理多个状态

备忘录模式的结构

复制代码
┌─────────────────────┐
│     Memento         │  备忘录
├─────────────────────┤
│ - state: Object     │
│ + getState(): Object│
└─────────────────────┘

┌─────────────────────┐
│    Originator       │  发起人
├─────────────────────┤
│ - state: Object     │
│ + save(): Memento   │
│ + restore(): void   │
└─────────────────────┘

┌─────────────────────┐
│     Caretaker       │  管理者
├─────────────────────┤
│ - mementos: List    │
│ + add(): void       │
│ + get(): Memento    │
└─────────────────────┘

代码示例

1. 定义备忘录

java 复制代码
/**
 * 备忘录:保存发起人的状态
 */
public class Memento {
    private String state;
    
    public Memento(String state) {
        this.state = state;
    }
    
    public String getState() {
        return state;
    }
}

2. 定义发起人

java 复制代码
/**
 * 发起人:需要保存状态的对象
 */
public class Originator {
    private String state;
    
    public void setState(String state) {
        this.state = state;
        System.out.println("当前状态: " + state);
    }
    
    public String getState() {
        return state;
    }
    
    /**
     * 创建备忘录
     */
    public Memento save() {
        System.out.println("保存状态: " + state);
        return new Memento(state);
    }
    
    /**
     * 恢复备忘录
     */
    public void restore(Memento memento) {
        this.state = memento.getState();
        System.out.println("恢复状态: " + state);
    }
}

3. 定义管理者

java 复制代码
/**
 * 管理者:管理备忘录
 */
public class Caretaker {
    private List<Memento> mementos = new ArrayList<>();
    
    /**
     * 添加备忘录
     */
    public void add(Memento memento) {
        mementos.add(memento);
        System.out.println("备忘录已保存,当前共有 " + mementos.size() + " 个备忘录");
    }
    
    /**
     * 获取备忘录
     */
    public Memento get(int index) {
        return mementos.get(index);
    }
    
    /**
     * 获取备忘录数量
     */
    public int size() {
        return mementos.size();
    }
}

4. 使用备忘录

java 复制代码
/**
 * 备忘录模式测试类
 * 演示如何使用备忘录模式保存和恢复状态
 */
public class MementoTest {
    
    public static void main(String[] args) {
        System.out.println("=== 备忘录模式测试 ===\n");
        
        // 创建发起人和管理者
        Originator originator = new Originator();
        Caretaker caretaker = new Caretaker();
        
        // 保存状态
        System.out.println("--- 保存状态 ---");
        originator.setState("状态1");
        caretaker.add(originator.save());
        
        originator.setState("状态2");
        caretaker.add(originator.save());
        
        originator.setState("状态3");
        caretaker.add(originator.save());
        
        System.out.println("\n--- 恢复状态 ---");
        System.out.println("当前状态: " + originator.getState());
        
        // 恢复到上一个状态
        System.out.println("\n恢复到上一个状态:");
        originator.restore(caretaker.get(caretaker.size() - 1));
        
        // 恢复到第一个状态
        System.out.println("\n恢复到第一个状态:");
        originator.restore(caretaker.get(0));
        
        // 恢复到第二个状态
        System.out.println("\n恢复到第二个状态:");
        originator.restore(caretaker.get(1));
        
        System.out.println("\n=== 备忘录模式的优势 ===");
        System.out.println("1. 保持封装:不暴露对象的内部状态");
        System.out.println("2. 可以撤销:可以撤销到之前的状态");
        System.out.println("3. 易于管理:易于管理多个状态");
        
        System.out.println("\n=== 实际应用场景 ===");
        System.out.println("1. 游戏存档:保存游戏进度");
        System.out.println("2. 文档撤销:撤销操作");
        System.out.println("3. 版本控制:版本控制系统");
        System.out.println("4. 数据库事务:事务回滚");
        
        System.out.println("\n=== 与命令模式的区别 ===");
        System.out.println("备忘录模式:保存对象的状态");
        System.out.println("命令模式:保存操作的历史");
        System.out.println("两者可以结合使用,实现完整的撤销功能");
    }
}

备忘录模式的优点

  1. 保持封装:不暴露对象的内部状态
  2. 可以撤销:可以撤销到之前的状态
  3. 易于管理:易于管理多个状态

备忘录模式的缺点

  1. 内存消耗:保存多个状态会消耗内存
  2. 性能开销:创建和恢复状态有性能开销

适用场景

  1. 需要撤销:需要撤销操作
  2. 需要保存:需要保存对象状态
  3. 保持封装:需要保持对象的封装性

常见应用场景

  • 游戏存档:保存游戏进度
  • 文档撤销:撤销操作
  • 版本控制:版本控制系统

使用建议

  • 需要撤销:使用备忘录模式
  • 需要保存:使用备忘录模式
  • 简单状态:直接保存即可

注意事项

⚠️ 备忘录模式虽然有用,但要注意:

  • 不要保存太多状态,消耗内存
  • 考虑使用命令模式
相关推荐
阿闽ooo3 天前
中介者模式打造多人聊天室系统
c++·设计模式·中介者模式
小米4963 天前
js设计模式 --- 工厂模式
设计模式
逆境不可逃3 天前
【从零入门23种设计模式08】结构型之组合模式(含电商业务场景)
线性代数·算法·设计模式·职场和发展·矩阵·组合模式
驴儿响叮当20103 天前
设计模式之状态模式
设计模式·状态模式
电子科技圈3 天前
XMOS推动智能音频等媒体处理技术从嵌入式系统转向全新边缘计算
人工智能·mcu·物联网·设计模式·音视频·边缘计算·iot
徐先生 @_@|||4 天前
安装依赖三方exe/msi的软件设计模式
设计模式
希望_睿智4 天前
实战设计模式之访问者模式
c++·设计模式·架构
茶本无香4 天前
设计模式之十六:状态模式(State Pattern)详解 -优雅地管理对象状态,告别繁琐的条件判断
java·设计模式·状态模式
驴儿响叮当20104 天前
设计模式之备忘录模式
设计模式·备忘录模式
驴儿响叮当20104 天前
设计模式之迭代器模式
设计模式·迭代器模式