look06888

导航

备忘录模式

备忘录模式-Memento Pattern

别名:快照模式-Snapshop Pattern 或令牌模式- Token Pattern

是什么?

是指在不破坏封装的前提下,捕获一个对象的内部状态,并且在对象之外保存这个状态,这样我们就可以在需要的时候将该对象恢复到原先保存的状态了。

可以做什么?

可以提供一种“后悔药”的机制,当你需要让对象返回之前的状态时,例如:你的用户请求“撤销”,就使用备忘录模式。

怎么实现的?

它通过存储系统中各个历史状态的快照,使得我们可以在任意时刻将系统回滚到历史状态。
通过堆栈方式:

应用场景

  • 编辑文档写文章的时候,经常写错,需要撤销的操作(Ctrl+Z),有这种需求的时候可以就用该模式。
  • 保存游戏进度,比如闯关模式,经常会挂掉,需要恢复到一个时间点。
  • SVN、Git 等都提供了历史版本的管理功能
  • 服务器的快照功能也可以让我们回退到历史状态
  • 应用场景总结:
    1.需要保存历史快照的场景
    2.希望在对象之外保存状态,且除了自己其他对象无法访问状态的具体保存内容

优缺点

  • 优点:简化了发起人的职责,将状态的存储和获取进行了隔离,而且客户端无需关心状态的保存细节。
  • 缺点:消耗资源,如果每个快照的内容都非常大,会消耗大量内存。

代码实现示例

文档类-Document
package com.muse.patterns.memento;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @description 文档类
 **/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Document {

    // 文档的内容
    private String content;

    public void print() {
        System.out.println("content=" + content);
    }
}

备忘录-Memento
package com.muse.patterns.memento;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * @description 备忘录
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Memento {

    // 文档内容
    public String content;
}

备忘录管理类-MememtoManager
package com.muse.patterns.memento;

import java.util.Stack;

/**
 * @description 备忘录管理类
 */
public class MementoManager {
    // 记录备忘录信息
    private Stack<MementomementoStack = new Stack<>();

    // 保存备忘录
    public void save(Document document) {
        Memento memento = new Memento(document.getContent());
        mementoStack.add(memento);
    }

    // 撤销操作ctrl+z
    public Document cancel() {
        Memento memento = mementoStack.pop();
        Document document = new Document();
        document.setContent(memento.getContent());
        return document;
    }
}

备忘录测试类-MementoTest
package com.muse.patterns.memento;

/**
 * 备忘录测试类
 */
public class MementoTest {
    public static void main(String[] args) {
        MementoManager mementoManager = new MementoManager();
        System.out.println("-----执行文档修改操作-----");
        Document document = new Document();
        document.setContent("a");
        document.print();
        mementoManager.save(document);

        document.setContent("b");
        document.print();
        mementoManager.save(document);

        document.setContent("c"); // 修改后,发现写错了,想要回撤到上一个保存点
        document.print();

        System.out.println("-----执行第一次撤销操作-----");
        document = mementoManager.cancel();
        document.print();

        System.out.println("-----执行第二次撤销操作-----");
        document = mementoManager.cancel();
        document.print();
    }
}

posted on 2024-02-13 14:19  Look068  阅读(6)  评论(0编辑  收藏  举报