设计模式系列-备忘录模式-Memento

介绍

我们经常使用的办公软件都有回退功能,你曾想过这样的功能是如何实现的呢?相比软件的回退功能比较复杂,我们还是举个对象状态回退的功能,要回退状态,首先得记录对象的历史状态数据,当回退到某个状态时,能从数据存储的地方恢复到对象状态里。通常我们把对象的状态数据封装起来,外部对象无权访问内部状态,如果状态暴露就易违反封装特性,会对代码的可靠性和扩展性作出妥协。
备忘录模式可以在不破坏对象封装特性的前提下解决我们上面的问题,也不会暴露对象的内部结构。为了更好的理解备忘录模式,我们举个案例来说明,创建一个类,有两个Double 类型的字段,然后基于这两个字段进行数学运算,同时支持回退操作,回到上一个运算结果状态。

备忘录模式详解

备忘录模式的目的是不违反封装原则,去捕获对象的内部状态并把状态存储在外部,将来可以利用存储的数据来恢复对象的状态。
主要参与者如下图:
在这里插入图片描述
** Originator **

  • 创建一个包含自己内部数据的备忘录(Memento)对象
  • 利用备忘录对象来恢复内部状态

** Caretaker **

  • 存储备忘录对象的集合
  • 不对备忘录对象进行操作

当想保存 originator 的某时刻状态时,先获取内部状态然后用来组装 Memento 对象,最后把 memento 对象保存在 Caretaker 对象中的集合里。Memento 对象必须隐藏 originator 的内部数据,只提供get 方法获取值,防止外部对象修改 originator 对象存档的内部状态。

代码实现

public class Originator {

    private double x;
    private double y;
    private String lastUndoSavePoint;
    CareTaker careTaker;

    public Originator(double x, double y, CareTaker careTaker) {
        this.x = x;
        this.y = y;
        this.careTaker = careTaker;
        createSavePoint("initial");
    }

    public void createSavePoint(String savePointName) {
        careTaker.saveMemento(savePointName, new Memento(this.x, this.y));
        this.lastUndoSavePoint = savePointName;
    }

    private void setOriginatorState(String savePointName){
        Memento memento = careTaker.getMemento(savePointName);
        this.x = memento.getX();
        this.y = memento.getY();
    }

    public void undo(){
        setOriginatorState(lastUndoSavePoint);
    }

    public void undo(String savePointName){
        setOriginatorState(savePointName);
    }

    public void undoAll(){
        setOriginatorState("initial");
        careTaker.clearSavePoints();
    }

    public double getX() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }

    @Override
    public String toString() {
        return "Originator{" +
                "x=" + x +
                ", y=" + y +
                '}';
    }
}

public class Memento {

    private final double x;
    private final double y;

    public Memento(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public double getX() {
        return x;
    }

    public double getY() {
        return y;
    }
}

public class CareTaker {

    private final Map<String, Memento> savePointStorage = new HashMap<>();

    public void saveMemento(String savePointName, Memento memento) {
        System.out.println("Save state..." + savePointName);
        savePointStorage.put(savePointName, memento);
    }

    public Memento getMemento(String savePointName) {
        System.out.println("Undo at..." + savePointName);
        return savePointStorage.get(savePointName);
    }

    public void clearSavePoints(){
        System.out.println("Clearing all save points...");
        savePointStorage.clear();
    }
}

public class TestMementoPattern {

    public static void main(String[] args) {
        CareTaker careTaker = new CareTaker();
        Originator originator = new Originator(1, 2, careTaker);
        originator.setY(6);
        originator.createSavePoint("save1");
        originator.undo();
        System.out.println("State: " + originator);
        originator.setX(10);
        originator.createSavePoint("save2");
        originator.setY(11);
        originator.createSavePoint("save3");
        originator.undo("save2");
        System.out.println("State: " + originator);
    }
}

输出结果:

Save state…initial
Save state…save1
Undo at…save1
State: Originator{x=1.0, y=6.0}
Save state…save2
Save state…save3
Undo at…save2
State: Originator{x=10.0, y=6.0}

需要记录某时刻对象状态的快照,并且将来能够复原的场景,需要考虑用备忘录模式,在Jdk 中使用此模式的例子

  • java.util.Date
  • java.io.Serializable
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
备忘录模式是一种行为型设计模式,它允许在不破坏封装性的前提下捕获对象的内部状态,并在对象之外保存这个状态,以便在以后的某个时候将其恢复到原先的状态。 备忘录模式由三个主要角色组成: 1. 发起人(Originator):负责创建一个备忘录,并记录和恢复自身的内部状态。 2. 备忘录(Memento):负责存储发起人对象的内部状态。 3. 管理者(Caretaker):负责保存备忘录,并可以对其进行管理,但不知道备忘录的具体内容。 该模式的工作流程如下: 1. 发起人创建一个备忘录,将自己的状态保存在备忘录中。 2. 发起人可以根据需要在任何时候保存自己的状态。 3. 管理者将备忘录保存起来,可维护多个备忘录。 4. 在需要恢复状态的时候,可以通过管理者获取相应的备忘录,并将发起人的状态恢复到备忘录中保存的状态。 备忘录模式的优点是: - 发起人对象与备忘录对象分离,实现了信息的封装和隐藏。 - 备忘录对象存储了发起人对象的历史状态,可以实现撤销和恢复操作。 - 备忘录可以进行存储和管理,可进行序列化和持久化操作。 备忘录模式通常适用于以下情况: - 需要保存和恢复对象的状态,并且封装对象的状态对于其他对象来说是不可见的。 - 需要实现撤销和恢复功能。 - 需要保存和恢复部分或全部对象状态的场景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值