【Java设计模式】备忘录模式

【Java设计模式】备忘录模式

一、概述

Java中的备忘录设计模式允许开发人员捕获和恢复对象的内部状态,而不违反封装。

二、详细解释及实际示例

  1. 实际示例
    • 一个文本编辑器应用程序可以利用Java中的备忘录设计模式来实现撤销和重做功能。通过在每次进行更改时将文档的当前状态捕获为备忘录,应用程序可以轻松地将文档恢复到任何以前的状态。这些快照存储在历史列表中。当用户点击撤销按钮时,编辑器将文档恢复到最近的备忘录中保存的状态。这个过程允许用户恢复到文档的以前版本,而无需暴露或更改编辑器的内部数据结构。
  2. 通俗解释
    • 备忘录模式捕获对象的内部状态,使其易于在任何时间点存储和恢复对象。
  3. 维基百科解释
    • 备忘录模式是一种软件设计模式,它提供了将对象恢复到其以前状态(通过回滚撤销)的能力。

三、Java中备忘录模式的编程示例

在我们的占星学应用程序中,我们使用备忘录模式来捕获和恢复星星对象的状态。每个状态都被保存为一个备忘录,允许我们根据需要恢复到以前的状态。
首先,让我们定义我们能够处理的星星类型。

public enum StarType {
    SUN("sun"),
    RED_GIANT("red giant"),
    WHITE_DWARF("white dwarf"),
    SUPERNOVA("supernova"),
    DEAD("dead star");
    //...
}

接下来,让我们直接跳到关键部分。这是Star类以及我们需要操作的备忘录。特别注意getMementosetMemento方法。

public interface StarMemento {
}
public class Star {
    private StarType type;
    private int ageYears;
    private int massTons;
    public Star(StarType startType, int startAge, int startMass) {
        this.type = startType;
        this.ageYears = startAge;
        this.massTons = startMass;
    }
    public void timePasses() {
        ageYears *= 2;
        massTons *= 8;
        switch (type) {
            case RED_GIANT -> type = StarType.WHITE_DWARF;
            case SUN -> type = StarType.RED_GIANT;
            case SUPERNOVA -> type = StarType.DEAD;
            case WHITE_DWARF -> type = StarType.SUPERNOVA;
            case DEAD -> {
                ageYears *= 2;
                massTons = 0;
            }
            default -> {
            }
        }
    }
    StarMemento getMemento() {
        var state = new StarMementoInternal();
        state.setAgeYears(ageYears);
        state.setMassTons(massTons);
        state.setType(type);
        return state;
    }
    void setMemento(StarMemento memento) {
        var state = (StarMementoInternal) memento;
        this.type = state.getType();
        this.ageYears = state.getAgeYears();
        this.massTons = state.getMassTons();
    }
    @Override
    public String toString() {
        return String.format("%s age: %d years mass: %d tons", type.toString(), ageYears, massTons);
    }
    private static class StarMementoInternal implements StarMemento {
        private StarType type;
        private int ageYears;
        private int massTons;
        // setters and getters ->
        //...
    }
}

最后,这是我们如何使用备忘录来存储和恢复星星状态的示例。

public static void main(String[] args) {
    var states = new Stack<StarMemento>();
    var star = new Star(StarType.SUN, 10000000, 500000);
    LOGGER.info(star.toString());
    states.add(star.getMemento());
    star.timePasses();
    LOGGER.info(star.toString());
    states.add(star.getMemento());
    star.timePasses();
    LOGGER.info(star.toString());
    states.add(star.getMemento());
    star.timePasses();
    LOGGER.info(star.toString());
    states.add(star.getMemento());
    star.timePasses();
    LOGGER.info(star.toString());
    while (!states.isEmpty()) {
        star.setMemento(states.pop());
        LOGGER.info(star.toString());
    }
}

程序输出:

14:09:15.878 [main] INFO com.iluwatar.memento.App -- sun age: 10000000 years mass: 500000 tons
14:09:15.880 [main] INFO com.iluwatar.memento.App -- red giant age: 20000000 years mass: 4000000 tons
14:09:15.880 [main] INFO com.iluwatar.memento.App -- white dwarf age: 40000000 years mass: 32000000 tons
14:09:15.880 [main] INFO com.iluwatar.memento.App -- supernova age: 80000000 years mass: 256000000 tons
14:09:15.880 [main] INFO com.iluwatar.memento.App -- dead star age: 160000000 years mass: 2048000000 tons
14:09:15.880 [main] INFO com.iluwatar.memento.App -- supernova age: 80000000 years mass: 256000000 tons
14:09:15.880 [main] INFO com.iluwatar.memento.App -- white dwarf age: 40000000 years mass: 32000000 tons
14:09:15.881 [main] INFO com.iluwatar.memento.App -- red giant age: 20000000 years mass: 4000000 tons
14:09:15.881 [main] INFO com.iluwatar.memento.App -- sun age: 10000000 years mass: 500000 tons

四、何时在Java中使用备忘录模式

当以下情况时使用备忘录模式:

  1. 您需要在Java中捕获对象的状态并在以后恢复它,而不暴露其内部结构。这对于维护封装和简化对象状态的管理至关重要。
  2. 直接获取状态的接口将暴露实现细节并破坏对象的封装。

五、备忘录模式在Java中的实际应用

备忘录模式在各种Java应用程序中使用,包括java.util.Datejava.util.Calendar类,它们可以恢复到以前的状态。它在文本编辑器和图形编辑器的撤销机制中也很常见。

六、备忘录模式的好处和权衡

好处:

  1. 保留封装边界。
  2. 通过消除直接管理版本历史或撤销功能的需求,简化了发起者。

权衡:

  1. 如果保存大量状态,可能会在内存方面昂贵。
  2. 必须注意管理备忘录的生命周期,以避免内存泄漏。

七、源码下载

备忘录模式示例代码下载

  • 10
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值