设计模式之备忘录模式(Memento)

版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/qq_23934475/article/details/83069181

设计模式之备忘录模式(Memento)

本篇为 https://github.com/iluwatar/java-design-patterns/tree/master/memento 阅读笔记

主要解决

所谓备忘录模式就是在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态。

应用例子

  • 后悔药
  • 打游戏存档
  • 浏览器后退

关键代码
客户不与备忘录类耦合,与备忘录管理类耦合。

场景

随时间的流逝恒星的年龄质量会变化,对恒星数据进行备份

恒星类型

public enum  StarType {

    SUN("sun"), RED_GIANT("red giant"), WHITE_DWARF("white dwarf"), SUPERNOVA("supernova"), DEAD(
      "dead star"), UNDEFINED("");

    private String title;

    StarType(String title) {
        this.title = title;
    }

    @Override
    public String toString() {
        return title;
    }
}

备忘录接口

public interface StarMemento {
}

Star类,类中含有成员内部类StarMementoInternal 实现了StarMemento 接口,实现数据复制

public class Star {

    private StarType type;
    private int ageYears;
    private int massTons;

    public Star(StarType type, int ageYears, int massTons) {
        this.type = type;
        this.ageYears = ageYears;
        this.massTons = massTons;
    }

    public void timePasses() {
        ageYears *= 2;
        massTons *= 8;
        switch (type) {
            case RED_GIANT:
                type = StarType.WHITE_DWARF;
                break;
            case SUN:
                type = StarType.RED_GIANT;
                break;
            case SUPERNOVA:
                type = StarType.DEAD;
                break;
            case WHITE_DWARF:
                type = StarType.SUPERNOVA;
                break;
            case DEAD:
                ageYears *= 2;
                massTons = 0;
                break;
            default:
                break;
        }
    }


    StarMemento getMemento() {

        StarMementoInternal state = new StarMementoInternal();
        state.setAgeYears(ageYears);
        state.setMassTons(massTons);
        state.setType(type);
        return state;

    }

    void setMemento(StarMemento memento) {

        StarMementoInternal 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;

        public StarType getType() {
            return type;
        }

        public void setType(StarType type) {
            this.type = type;
        }

        public int getAgeYears() {
            return ageYears;
        }

        public void setAgeYears(int ageYears) {
            this.ageYears = ageYears;
        }

        public int getMassTons() {
            return massTons;
        }

        public void setMassTons(int massTons) {
            this.massTons = massTons;
        }
    }
}

测试

  @Test
    public void mementoTest(){
        Stack<StarMemento> states = new Stack<>();

        Star star = new Star(StarType.SUN, 10000000, 500000);
        System.out.println(star.toString());
        states.add(star.getMemento());
        star.timePasses();
        System.out.println(star.toString());
        states.add(star.getMemento());
        star.timePasses();
        System.out.println(star.toString());
        states.add(star.getMemento());
        star.timePasses();
        System.out.println(star.toString());
        states.add(star.getMemento());
        star.timePasses();
        System.out.println(star.toString());
        while (states.size() > 0) {
            star.setMemento(states.pop());
            System.out.println(star.toString());
        }

    }

类图

猜你喜欢

转载自blog.csdn.net/qq_23934475/article/details/83069181