Java设计模式之备忘录模式

>>最全面的Java面试大纲及答案解析(建议收藏)  

在不破坏封装的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可以将该对象恢复至原先保存的状态。

备忘录模式涉及角色

  • Originator(发起人):负责创建一个备忘录Memento,用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。Originator可以根据需要决定Memento存储自己的哪些内部状态。

  • Memento(备忘录):负责存储Originator对象的内部状态,并可以防止Originator以外的其他对象访问备忘录。备忘录有两个接口:Caretaker只能看到备忘录的窄接口,他只能将备忘录传递给其他对象。Originator却可看到备忘录的宽接口,允许它访问返回到先前状态所需要的所有数据。

  • Caretaker(管理者):负责备忘录Memento,不能对Memento的内容进行访问或者操作。

UML结构图如下所示:

Java设计模式之备忘录模式

案例场景

我们都玩过魔塔这个游戏,里面的角色有生命值、攻击力和层数的数值,每上一层数值都会发生变化,当打怪时感觉自己打不过时可以进行存档。

具体实现代码:

备忘录接口

public interface IMemento {

}

管理者

public class MementoCaretaker {
    private HashMap<String, IMemento> mementoMap;

    public MementoCaretaker() {
        mementoMap = new HashMap<String, IMemento>();
    }

    /**
     * 获取
     *
     * @param name
     * @return
     */

    public IMemento retrieveMemento(String name) {
        return mementoMap.get(name);
    }

    /**
     * 赋值方法
     *
     * @param name
     * @param memento
     */

    public void saveMemento(String name, IMemento memento) {
        this.mementoMap.put(name, memento);
    }
}

发起者

public class Originator1 {
    private HashMap<String, String> state;

    public Originator1() {
        state = new HashMap();
    }

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

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

    public void showState() {
        System.out.println("now state:" + state.toString());
    }

    public void testState1() {
        state.put("血量""1000");
        state.put("攻击力""500");
        state.put("层数""1");
    }

    public void testState2() {
        state.put("血量""3500");
        state.put("攻击力""1500");
        state.put("层数""10");
    }

    private class Memento implements IMemento {
        private HashMap<String, String> state;

        private Memento(HashMap state) {
            this.state = new HashMap(state);
        }

        private HashMap getState() {
            return state;
        }

        private void setState(HashMap state) {
            this.state = state;
        }
    }
}

测试类

public class MementoTest {

    public static void main(String[] args) {
        MementoCaretaker mementoCaretaker = new MementoCaretaker();
        Originator1 originator1 = new Originator1();
        System.out.println("发起者originator1");
        originator1.testState1();
        originator1.showState();
        mementoCaretaker.saveMemento("originator", originator1.createMemento());
        originator1.testState2();
        originator1.showState();
        originator1.restoreMemento(mementoCaretaker.retrieveMemento("originator"));
        originator1.showState();

    }
}

测试结果如下所示:

Java设计模式之备忘录模式

以上便是备忘录模式的具体实现。

总结

备忘录模式可以把发起人内部信息对象屏蔽起来,从而可以达到保持封装的边界。当发起人的状态出现问题时,可以很轻松的恢复。

END


原文始发于微信公众号(一盏红茶):Java设计模式之备忘录模式