备忘录模式与编辑器

本文通过Editor.java和Snapshot.java代码展示了备忘录模式的应用,如何通过创建SnapShot对象保存编辑器的状态,并在需要时通过撤销操作恢复。Memento模式在编辑器中扮演关键角色,支持复杂文本编辑历史管理。
摘要由CSDN通过智能技术生成

备忘录模式

备忘录模式是一种行为设计模式,允许在不暴露对象细节的情况下保存和恢复对象之前的状态

编辑器

接下来我们用编辑器的例子感受一下备忘录模式。

Editor.java

/**
 * 编辑器
 */
public class Editor {
    //历史信息栈,先进后出,最大保存个数2个
    private final LimitStack history = new LimitStack(2);
    private String text;
    private int cursorBegin;
    private int cursorEnd;

    /**
     * 保存
     */
    public void save(){
        history.addLast(createSnapShot());
    }

    /**
     * 撤销
     */
    public void revoke(){
        SnapShot snapShot = history.popLast();
        if (snapShot != null) {
            restore(snapShot);
        }
    }

    /**
     * 还原到指定版本
     * @param snapShot
     */
    public void restore(SnapShot snapShot){
        LoggerFactory.getLogger("Editor.restore").info("{}", snapShot);
        setText(snapShot.getText());
        setCursorBegin(snapShot.getCursorBegin());
        setCursorEnd(snapShot.getCursorEnd());
    }

    public SnapShot createSnapShot(){
        SnapShot snapShot = new SnapShot(text, cursorBegin, cursorEnd);
        LoggerFactory.getLogger("Editor.createSnapShot").info("{}",snapShot);
        return snapShot;
    }

    public String getText() {
        return text;
    }

    public void setText(String text) {
        this.text = text;
        this.cursorBegin = text.length();
        this.cursorEnd = text.length();
        LoggerFactory.getLogger("Editor.setText").info("{}", text);
    }

    public int getCursorBegin() {
        return cursorBegin;
    }

    public void setCursorBegin(int cursorBegin) {
        this.cursorBegin = cursorBegin;
    }

    public int getCursorEnd() {
        return cursorEnd;
    }

    public void setCursorEnd(int cursorEnd) {
        this.cursorEnd = cursorEnd;
    }

    @Override
    public String toString() {
        return "Editor{" +
                "text='" + text + '\'' +
                ", cursorBegin=" + cursorBegin +
                ", cursorEnd=" + cursorEnd +
                '}';
    }

    /**
     * 先进后出的定长栈
     */
    private static class LimitStack {

        private final int count;
        private final SnapShot[] array;
        private int index=-1;

        private LimitStack(int count) {
            this.count = count;
            this.array = new SnapShot[count];
            LoggerFactory.getLogger("LimitStack").info("可保存的历史总数{}", count);
        }

        /**
         * 向队尾插入一个
         */
        public void addLast(SnapShot snapShot){
            index++;
            array[index%count] = snapShot;
            LoggerFactory.getLogger("LimitStack.addLast").info("{}", snapShot);
        }

        public SnapShot popLast(){
            int i = index % count;
            SnapShot snapShot = array[i];
            array[i] = null;
            index--;
            LoggerFactory.getLogger("LimitStack.popLast").info("{}", snapShot);
            return snapShot;
        }
    }
}

Snapshot.java

public class SnapShot {
    private final String text;
    private final int cursorBegin;
    private final int cursorEnd;
    private final LocalDateTime creatTime;

    SnapShot(String text, int cursorBegin, int cursorEnd){
        this.text = text;
        this.cursorBegin = cursorBegin;
        this.cursorEnd = cursorEnd;
        creatTime = LocalDateTime.now();
    }

    public LocalDateTime getCreatTime() {
        return creatTime;
    }

    public String getText() {
        return text;
    }

    public int getCursorBegin() {
        return cursorBegin;
    }

    public int getCursorEnd() {
        return cursorEnd;
    }

    @Override
    public String toString() {
        return "SnapShot{" +
                "text='" + text + '\'' +
                ", cursorBegin=" + cursorBegin +
                ", cursorEnd=" + cursorEnd +
                ", creatTime=" + creatTime +
                '}';
    }
}

MementoMain.java

public class MementoMain {
    public static void main(String[] args) {
        Editor editor = new Editor();
        editor.setText("大家好!");
        editor.save();
        editor.setText(editor.getText()+"我是");
        editor.save();
        editor.setText(editor.getText()+"张三");
        editor.save();
        editor.setText(editor.getText()+",法外狂徒");
        editor.revoke();
        editor.revoke();
        editor.revoke();
    }
}

运行结果

在这里插入图片描述

总结

  • 在备忘录模式中存在三个角色:

    1. 原发器(Originator):可以生成自身状态的快照,也可以在需要的时候通过快照恢复自身状态,就好像上面代码中的Editor一样。
    2. 备忘录(Memento):是原发器快照的值对象(value object)。通常做法是将备忘录设置为不可变的,并通过构造函数一次性传递数据,就好像上面代码中的Snapshot一样,Snapshot中存储了Editor实例的状态信息,并且所有的信息都是final类型的。
    3. 负责人(Caretaker):通过保存备忘录栈来记录原发器的历史状态。 就好像LimitStack一样。
  • 应用场景:

    1. 当你需要创建对象快照来恢复其之前的状态时,可以使用备忘录模式,比如各种类型的编辑器。
    2. 需要提供保存与恢复的业务场景,比如游戏中的存档和读档。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值