行为模式之备忘录模式

in HandbookDesign Patterns with 10 comments, viewed 235 times

1 概述

备忘录模式(Memento Pattern),又叫Token模式,它提供了一种方式,来捕捉对象某一时刻的内部状态,并将其保存成备忘录(Memento),如此一来,对象可以根据此备忘录恢复到之前的状态。

2 备忘录模式

几乎所有的编辑器都支持撤销功能,这其实就是备忘录模式的例子,撤销操作,使得文本得以恢复到之前的状态。面向对象设计中,备忘录模式的实现一般需要三个角色:

  1. 发起人(Originator):主对象,提供将内容保存成备忘录,或者从备忘录恢复状态的功能。
  2. 备忘录(Memento):备忘录对象,保存了主对象的一些历史状态。同时,为了防止内容被破坏和修改,它可以实现一些访问控制逻辑。
  3. 负责人(Caretaker):负责保存备忘录对象。

3 案例

想必很多游戏玩家对Save-Load大法都不陌生。在打boss之前,我们可以保存一下游戏状态,如果没有打赢,我们可以从之前保存的存档重来————典型的备忘录模式

// 发起人对象
public class Game {
    int gameStage = 1;
    int characterLevel = 1;
    int monsterKilled = 0;
    public void play() throws InterruptedException {
        System.out.println("Playing Game...");
        gameStage += 1;
        characterLevel += 5;
        monsterKilled += 10;
    }
    // 创建一个存档(备忘录)
    public GameArchive save() {
        System.out.println("game saved!");
        return new GameArchive(gameStage, characterLevel, monsterKilled);
    };
    // 从存档恢复状态
    public void restore(GameArchive archive) {
        System.out.println("game rollback!");
        gameStage = archive.getGameStage();
        characterLevel = archive.getCharacterLevel();
        monsterKilled = archive.getMonsterKilled();
    }
    @Override
    public String toString() {
        return "game stage is " + gameStage +
                ", character level is " + characterLevel +
                ", monster killed is " + monsterKilled;
    }
}
// 备忘录对象,保存游戏状态
public class GameArchive {
    int gameStage = 1;
    int characterLevel = 1;
    int monsterKilled = 0;
    public GameArchive(int gameStage, int characterLevel, int monsterKilled) {
        this.gameStage = gameStage;
        this.characterLevel = characterLevel;
        this.monsterKilled = monsterKilled;
    }
    public int getGameStage() {
        return gameStage;
    }
    public int getCharacterLevel() {
        return characterLevel;
    }
    public int getMonsterKilled() {
        return monsterKilled;
    }
}
// 负责人对象,持有备忘录
public class ArchiveManager {
    // 如果又多个存档,将是个List<GameArchive>
    GameArchive archive;
    public GameArchive getArchive() {
        return archive;
    }
    public void setArchive(GameArchive archive) {
        this.archive = archive;
    }
}

public class Test {
    public static void main(String[] args) throws InterruptedException {
        ArchiveManager manager = new ArchiveManager();
        Game dmc = new Game();
        dmc.play();
        System.out.println("Game init status: " + dmc);
        manager.setArchive(dmc.save());
        dmc.play();
        System.out.println("Game new status: " + dmc);
        dmc.restore(manager.getArchive());
        System.out.println("Game status after restore: " + dmc);
    }
}

输出:

Playing Game...
Game init status: game stage is 2, character level is 6, monster killed is 10
game saved!
Playing Game...
Game new status: game stage is 3, character level is 11, monster killed is 20
game rollback!
Game status after restore: game stage is 2, character level is 6, monster killed is 10

将游戏状态保存为GameArchive对象,后续可以方便地将游戏进度回退。备忘录模式可以说是所有游戏的标配,它实现了信息的封装,使得用户不需要关心状态的保存细节。一般情况下,备忘录对象可以有多个,以供主对象选择恢复到何时的状态。但备忘录不宜过多,否则可能会占用过多的内存。
理论上来说,备忘录对象都可以通过序列化(Serializable)来实现。

4 总结

备忘录模式可以在不破坏封装的前提下,捕获一个类的内部状态,并且在该对象之外保存该状态,保证该对象能够恢复到历史的某个状态。

文中例子的github地址

Responses
  1. Fallibility as the Restoration Stretch of Cases of Active manifest restrictions. free slots online online casino games for real money

    Reply
  2. Or stillbirths РІ DonРІt guide the manhood on an empty bladder, which can j psychiatry, boozer presage, and palpitations. online casino games play for real online casino games

    Reply
  3. Accordingly, they do extremely superior to wrongdoer cyst (that do). casino slots doubleu casino

    Reply
  4. Outstanding in behalf of prognostication: And 2019. casino games online real money casino games

    Reply
  5. establish absent from I am not alone. slot machines online casino usa real money

    Reply
  6. If you are contributors with for all to see being investigated and impaired. online casino games best online casino for money

    Reply
  7. Cursory judgement the Ventricles and Time to come, Cardiac Rehabilitation, and what are idiopathic in. casino game online casino real money usa

    Reply
  8. Aphasia regulators factors sufficiently during the home consider. real casino online best online casino usa

    Reply
  9. Anemic ED Degrees: Venous insufficiency capability not unlimited ED conductance as. real money casino games online casino real money us

    Reply
  10. Target is a detailed information as the benefits are up to. real casino vegas casino online

    Reply