Java设计模式--备忘录模式

1 Memento Pattern 备忘录模式

目的:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态;
实现:客户不与备忘录类耦合,与备忘录管理类耦合,通过一个备忘录类专门存储对象状态。

1.并在该对象之外保存这个状态,这样可以在以后将对象恢复到原先保存的状态;
2.很多时候我们总是需要记录一个对象的内部状态,这样做的目的就是为了允许用户取消不确定或者错误的操作,能够恢复到他原先的状态,使得他有”后悔药”可吃。

2 实现

代码场景:西汉王朝继秦朝之后的大一统王朝,每年都在发生着大事,太史令司马迁负责将这些事件记录到史书中以供后世查看。
1.原发器角色西汉王朝;
2.备忘录角色历史事件;
3.负责人角色司马迁

因案例是真实历史事件,故不提供时光倒流的实现。
在使用该模式时可根据需要提供”后悔药”方法。

2.1 代码实现

原发器角色:西汉王朝

public class Han {
    //事件
    private String thing;
    public String getThing() {
        return thing;
    }
    public void setThing(String thing) {
        this.thing = thing;
    }
}

备忘录角色:历史事件

public class History {
    private String thing;
    public History(String thing) {
        this.thing = thing;
    }

    public String getThing() {
        return thing;
    }
}

负责人角色:司马迁

public class SiMaQian {
    private Map<String, History> historyMap = new HashMap<String, History>();

    public void addHistoryList(String year, History history) {
        historyMap.put(year, history);
    }

    public History getHistoryList(String year) {
        if (historyMap.containsKey(year)) {
            return historyMap.get(year);
        }
        return null;
    }
}

2.2 涉及角色

在备忘录模式结构图中包含如下几个角色:

Originator(原发器):它是一个普通类,可以创建一个备忘录,并存储它的当前内部状态,也可以使用备忘录来恢复其内部状态,一般将需要保存内部状态的类设计为原发器。

Memento(备忘录):存储原发器的内部状态,根据原发器来决定保存哪些内部状态。备忘录的设计一般可以参考原发器的设计,根据实际需要确定备忘录类中的属性。需要注意的是,除了原发器本身与负责人类之外,备忘录对象不能直接供其他类使用,原发器的设计在不同的编程语言中实现机制会有所不同。

Caretaker(负责人):负责人又称为管理者,它负责保存备忘录,但是不能对备忘录的内容进行操作或检查。在负责人类中可以存储一个或多个备忘录对象,它只负责存储对象,而不能修改对象,也无须知道对象的实现细节。

2.3 调用

调用者:

public class Client {
    public static void main(String[] args) {
        // 大汉帝国
        Han han = new Han();
        // 汉武帝建元年间 司马到长安任太史令
        System.out.println("汉武帝建元年间,司马到长安任太史令。");
        SiMaQian sm = new SiMaQian();
        // 公元前108年
        han.setThing("天下大旱。");
        History h = new History(han.getThing());
        sm.addHistoryList("公元前108年", h);
        // 公元前104年
        han.setThing("汉朝历法改革,制定<<汉历>>。");
        History h1 = new History(han.getThing());
        sm.addHistoryList("公元前104年", h1);
        // 公元前99年
        han.setThing("李陵率步兵五千涉单于庭以寡击众,粮尽矢绝后,被迫投降。");
        History h2 = new History(han.getThing());
        sm.addHistoryList("公元前99年", h2);

        System.out.println("公元前108年:" + sm.getHistoryList("公元前108年").getThing());
        System.out.println("公元前104年:" + sm.getHistoryList("公元前108年").getThing());
        System.out.println("公元前99年:" + sm.getHistoryList("公元前108年").getThing());
        // 历史不可倒退 故无法回到过去
    }
}

结果:

汉武帝建元年间,司马到长安任太史令。
公元前108年:天下大旱。
公元前104年:天下大旱。
公元前99年:天下大旱。

代码地址:点击跳转
设计模式汇总:点击跳转

参考文献:
[ 1 ] 图解设计模式/(日)结城浩著;杨文轩译。–北京:人民邮电出版社,2017.1.
[ 2 ] 维基百科 设计模式
[ 3 ] 极客学院WIKI–设计模式.
[ 4 ] 菜鸟教程–设计模式.

猜你喜欢

转载自blog.csdn.net/weixx3/article/details/80248151