Memento(备忘录)

Memento(备忘录) 行为型 对象 1

Intent_意图2

在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态

Motivation_动机3

备忘录对象是一个用来存储另一个对象内部状态的快照的对象。备忘录模式的用意是在不破坏封装的条件下,将一个对象的状态捕捉住,并外部化,存储起来,从而可以在将来合适的时候把这个对象还原到存储起来的状态。备忘录模式常常与命令模式和迭代子模式一同使用

Applicability_适用性4

为了允许用户取消不确定或错误的操作,将对象的内部状态记录下来,当需要的时候,能恢复到对象原先的状态

Structure_结构5

在这里插入图片描述

Participants_参与者6

  • Originator(发起人) 记录当前时刻的状态,负责定义哪些属于需要备份的状态,负责创建和恢复备忘录数据
  • Memento(备忘录) 负责存储发起人的状态
  • Caretaker(备忘录管理员) 对备忘录进行管理和保存

Collaborations_协作7

  1. Memento将Originator对象的内部状态存储起来
    -> Memento可以根据Originator对象的判断来决定存储多少Originator对象的内部状态。
    -> Memento可以保护其内容不被Originator对象之外的任何对象所读取
    -> Memento有两个等效接口:
    -> narrow(窄接口):Caretaker对象(和其他除Originator对象之外的任何对象)看到的是Memento的narrow interface(窄接口),narrow只允许把Memeto对象传给其他的对象
    -> wide(宽接口):与narrow相反,Originator对象可以看到一个wide interface(宽接口),wide允许它读取所有的数据,以便根据这些数恢复Originator对象的内部状态
  2. Originator负责创建一个含有当前内部状态的Memento对象,并使用Memento对象来存储其内部状态
  3. Caretaker负责保存Memento对象,不检查Memento对象的内容

Comsequences_结果8

  • 优点
    将被储存的状态放在外面,不要和关键对象混在一起,可以帮助维护内聚
    保持关键对象的数据封装
    提供了容易实现的恢复能力
  • 缺点
    当成员变量过多,储存和恢复状态的过程可能相当耗时
  • 用途
    需要保存/恢复数据的相关状态场景
    提供一个可回滚的操作

Implementation/Sample Code_实现/范例代码910

Implementation

Memento

public class Memento {
    private String state;

    public Memento(String state) {
        this.state = state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getState() {
        return state;
    }
}

Originator

public class Originator {
    private String state;

    public Memento createMemento() {
        return new Memento(state);
    }

    public void restoreMemento(Memento memento) {
        this.state = memento.getState();
    }

    public void setState(String state) {
        this.state = state;
        System.out.println("Current state: " + this.state);
    }

    public String getState() {
        return state;
    }
}

Caretaker

public class Caretaker {
    public Memento memento;

    public Memento retrieveMemento() {
        return memento;
    }

    public void saveMemento(Memento memento) {
        this.memento = memento;
    }
}

Sample Code

Client

public class Client {
    public static void main(String[] args) {
        Originator originator = new Originator();
        Caretaker caretaker = new Caretaker();
        // change Originator's state
        originator.setState("On");
        // create Memento, and save Originator's state
        caretaker.saveMemento(originator.createMemento());
        // change Originator's state
        originator.setState("Off");
        // restore Originator's state
        originator.restoreMemento(caretaker.retrieveMemento());

        System.out.println(originator.getState());
    }
}

Result

Current state: On
Current state: Off
On

Known Uses_已知应用11

Related Patterns_相关模式12

“白盒”备忘录:Memento对任何对象都提供一个接口,即宽接口,Memento的内部所存储的状态对所有对象公开
在这里插入图片描述
“黑盒”备忘录:Memento对Originator提供一个宽接口,而为其他对象提供一个窄接口,将Memento设计成Originator类的内部类,从而将Memento对象封装在Originator里面,在外部提供一个标识接口给Caretaker以及其他对象。这样,Originator类看到的是Memento的所有接口,而Caretaker以及其他对象仅能看到标识接口MementoIF所暴露出来的接口
在这里插入图片描述


  1. 模式分类归属 ↩︎

  2. 意图:描述该模式的作用,以及该模式的定义 ↩︎

  3. 动机:给出了问题以及如何解决这个问题的具体场景 ↩︎

  4. 适用性:描述模式可以被应用在什么场合 ↩︎

  5. 结构:提供了图示,显示出参与此模式的类之间的关系 ↩︎

  6. 参与者:描述在此设计中所涉及到的类和对象在模式中的责任和角色 ↩︎

  7. 协作 :告诉参与者如何在此模式中合作 ↩︎

  8. 结果:描述采用此模式之后可能产生的效果,好的与不好的 ↩︎

  9. 实现:提供了在实现该模式时需要使用的技巧,以及应该小心面对的问题 ↩︎

  10. 范例代码:提供代码的片段 ↩︎

  11. 已知应用:用来描述已经在真实系统中发现的模式例子 ↩︎

  12. 相关模式:描述了此模式和其他模式之间的关系 ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值