16、备忘录模式(Memento Pattern)

2020-08-19  本文已影响0人  火山_6c7b

1. 备忘录模式

1.1 简介

  备忘录模式是一种软件设计模式,它提供一种能将一个对象恢复到旧状态的能力(回滚式的撤销操作)。备忘录模式又叫做快照模式(Snapshot Pattern)或Token模式,是对象的行为模式。Memento Pattern在不破坏封闭的前提下,捕获并外部化一个对象的内部状态,这样之后就可以将该对象恢复到保存时的状态。

  在应用软件的开发过程中,很多时候我们都需要记录一个对象的内部状态。在具体实现过程中,为了允许用户取消不确定的操作或从错误中恢复过来,需要实现备份点和撤销机制,而要实现这些机制,必须事先将状态信息保存在某处,这样才能将对象恢复到它们原先的状态。备忘录模式是一种给我们的软件提供后悔药的机制,通过它可以使系统恢复到某一特定的历史状态。

  备忘录模式通过三个对象来实现:originator、caretaker和memento。originator是一些拥有内部状态的对象。caretaker将在originator之上进行一些处理,但是同时希望能够撤销之前的处理操作。caretaker首先向originator请求一个memento对象,然后它将进行它所要进行的任何操作。为了回滚回进行这些操作的状态,caretaker将返回memento对象给originator。memento对象是一种不透明对象(caretaker不能也不应该对其改变)。使用这种模式的时候,需要注意的是originator可能改变其他对象或资源的状态,备忘录模式只对单一对象起作用。

1.2 Memento Pattern的uml

Memento uml.png

Memento Pattern的角色:

2. Memento Pattern的示例

  我们以游戏为示例,游戏角色拥有生命值和经验值,每一次打怪升级都需要消耗生命值和经验值,冷却足够时间后都会恢复。

** GamePlayer:**

// Originator
public class GamePlayer {

    // 遊戲角色的生命值
    private int mHp;

    // 遊戲角色的經驗值
    private int mExp;

    public GamePlayer(int hp, int exp)
    {
        mHp = hp;
        mExp = exp;
    }

    public GameMemento saveToMemento()
    {
        return new GameMemento(mHp, mExp);
    }

    public void restoreFromMemento(GameMemento memento)
    {
        mHp = memento.getGameHp();
        mExp = memento.getGameExp();
    }

    public void play(int hp, int exp)
    {
        mHp = mHp - hp;
        mExp = mExp + exp;
    }
}

** GameMemento:**

// Memento
public class GameMemento {

    // 假設只有這兩個資料要保留
    private int mGameHp;
    private int mGameExp;

    public GameMemento(int hp, int exp)
    {
        mGameHp = hp;
        mGameExp = exp;
    }

    public int getGameHp()
    {
        return mGameHp;
    }

    public int getGameExp()
    {
        return mGameExp;
    }
}

** Caretaker:**

// Caretaker
public class GameCaretaker {

    // 保留要處理的資料。
    // 這邊只是範例,所以 Caretaker
    // 只能處理一個 Memento。
    // 實務上當然可以用更複雜的結構來
    // 處理多個 Memento,如 ArrayList。
    private GameMemento mMemento;

    public GameMemento getMemento()
    {
        return mMemento;
    }

    public void setMemento(GameMemento memento)
    {
        mMemento = memento;
    }
}

** 客户端调用示例:**

 public static void main(String[] args)
    {
        // 創造一個遊戲角色
        GamePlayer player = new GamePlayer(100, 0);

        // 先存個檔
        GameCaretaker caretaker = new GameCaretaker();
        caretaker.setMemento(player.seveToMemento());

        // 不小心死掉啦
        player.play(-100, 10);

        // 重新讀取存檔,又是一尾活龍
        player.restoreFromMemento(caretaker.getMemento());
    }

3. 总结

备忘录模式的优点:

备忘录模式的缺点:

备忘录模式适用环境:

备忘录模式应用:

备忘录模式扩展:
备忘录的封装性

上一篇 下一篇

猜你喜欢

热点阅读