IT铁人DAY 26-Memento 备忘录模式

  今天要学习的模式我觉得很有趣,学完以後很常拿它用来做 undo、redo 的功能,因为它的功能就是用来保存和恢复物件的状态的,现在就来认识一下吧!


问题情境与解析

  现在有个文字编辑器,在执行任何操作之前,此编辑器就会记录所有物件的状态并且储存到一个地方去,而当用户想要恢复上一个状态的时候,编辑器就会从历史纪录中拿到最近一笔的物件快照来恢复所有物件的状态。

  但如果要产生这些物件快照的话,就会需要取的物件的所有属性才能够复制到储存的地方去,但是大多数的物件不会开放所有属性给其它人存取,有些重要的资讯会存成私有属性,这可能就会造成物件快照不完全。

  而备忘录模式会将创建物件快照的方法封装到实际所有者(Originator)本身,因此不是其它物件从外部复制编辑器的状态,是编辑器本身可以自己创建快照,如此就没有公有、私有属性的存取问题了。

  这些快照会储存在Memento类别中,再由Caretaker类别统一做管理,但不能修改Memento中的状态,若是想要恢复上一个状态的话,Originator可以存取Memento中的所有属性来恢复。

Class Diagram

https://ithelp.ithome.com.tw/upload/images/20211011/20140743up8vKBQrU2.png

Skeleton Code

import java.util.LinkedList;

class Caretaker {
    private Originator originator;
    private LinkedList<Memento> history = new LinkedList<Memento>();
    
    public Caretaker(Originator originator) {
        this.originator = originator;
    }
    
    public void saveMemento() {
        history.push(originator.save());
    }
    
    public void undo() {
        originator.restore(history.pop());
    }
}

class Memento {
    private State state;
    
    public Memento(State state) {
        this.state = state;
    }
    
    public State getState() {
        return state;
    }
}

class Originator {
    private State state;
    
    public Memento saveToMemento() {
        return new Memento(state);
    }
    
    public void restore(Memento m) {
        this.state = m.getState();
    }
}

  看完以後是不是也觉得Memento很适合拿来做上一步、下一步的功能呢!它可以不违反封装的情况下生成物件快照,而且这些快照会让Caretaker来管理,作为Originator状态的历史纪录,使用者有需要的时候就可以拿来做恢复的动作。不过使用者过於频繁的创建Memento的话,那系统可能就会消耗许多记忆体,这点可能要稍稍留意。


除此之外,也欢迎大家走走逛逛关於我们团队夥伴的文章

lu23770127 - SASS 基础初学三十天

10u1 - 糟了!是世界奇观!

juck30808 - Python - 数位行销分析与 Youtube API 教学

SiQing47 - 前端?後端?你早晚都要全端的,何不从现在开始?


<<:  Leetcode: 101. Symmetric Tree

>>:  [Day26]约束规则、更改结构

JavaScript Day 10. 阵列

为什麽需要学到阵列? 假设今天这里有100样东西,我们必须设法执行它,而这时候如果不使用阵列,东西都...

Day28|再撑一下下

一边准备婚礼、一边运动节食、一边铁人赛... 真的很累!! 加上新工作很忙碌,每天都累到很想哭 .....

Day 18 wait group 的使用

Wait group wait group 通常用来等待一组 goroutine 完成工作。 wai...

[day6]API串接-Message内文加密

在串接API时,遇到最大的坎就是Message内文加密了, 就让我们来试看看罗~ Message内文...

为了转生而点技能~day1:javascript 起手篇(RHS、LHS、语法作用域

本系列是为了转生,为了点技能而解任务的攻略提示,皆无营利、亦非营利取向。 Javascript:属於...