IT职涯

一个多年的IT人的博客
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

Java设计模式十五:备忘录模式(Memento)

Posted on 2012-12-12 16:04  IT职涯  阅读(2180)  评论(0编辑  收藏  举报

备忘录模式又叫做快照模式(Snapshot Pattern)或Token模式,属于行为模式。它是在不破坏封闭的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态,这样以后就可将该对象恢复到原先保存的状态。

类图:


组成部分:
发起人(Originator): 负责创建一个备忘录Memento,用以记录当前时刻自身的内部状态,并可使用备忘录恢复内部状态。发起人可以根据需要觉得备忘录存储自己的哪些内部状态。
备忘录(Memento): 负责存储发起人对象的内部状态,并可以防止发起人以外的其他对象访问备忘录。备忘录有两个接口:管理者只能看到备忘录的窄接口,他只能将备忘录传递给其他对象。发起人却可以看到备忘录的宽接口,允许它访问返回到先前状态所需要的所有数据。
管理者(Caretaker): 负责备忘录,不能对备忘录的内容进行访问或者操作。

实例:以保存游戏进度为例,在游戏角色大战Boss前将该角色的状态存储,与Boss作战后角色的各项能力会下降,如果没有通关,则可利用备忘录进行恢复到战前状态。

public class Memento
{
    private int vitality;
    private int aggressivity;
    private int defencivity;

    public int getVitality()
    {
        return vitality;
    }

    public void setVitality(final int vitality)
    {
        this.vitality = vitality;
    }

    public int getAggressivity()
    {
        return aggressivity;
    }

    public void setAggressivity(final int aggressivity)
    {
        this.aggressivity = aggressivity;
    }

    public int getDefencivity()
    {
        return defencivity;
    }

    public void setDefencivity(final int defencivity)
    {
        this.defencivity = defencivity;
    }
}


public class PlayerOriginator
{
    private int vitality; //生命力
    private int aggressivity; //攻击力
    private int defencivity; //防御力

    public PlayerOriginator(final int vitality, final int aggressivity, final int defencivity)
    {
        this.vitality = vitality;
        this.aggressivity = aggressivity;
        this.defencivity = defencivity;
    }

    public int getVitality()
    {
        return vitality;
    }

    public void setVitality(final int vitality)
    {
        this.vitality = vitality;
    }

    public int getAggressivity()
    {
        return aggressivity;
    }

    public void setAggressivity(final int aggressivity)
    {
        this.aggressivity = aggressivity;
    }

    public int getDefencivity()
    {
        return defencivity;
    }

    public void setDefencivity(final int defencivity)
    {
        this.defencivity = defencivity;
    }

    public Memento createMemento()
    {
        final Memento memento = new Memento();
        memento.setVitality(this.vitality);
        memento.setAggressivity(this.aggressivity);
        memento.setDefencivity(this.defencivity);
        return memento;
    }

    public void setMemento(final Memento memento)
    {
        this.vitality = memento.getVitality();
        this.aggressivity = memento.getAggressivity();
        this.defencivity = memento.getDefencivity();
    }

    public void showState()
    {
        System.out.print("vitality:" + this.vitality);
        System.out.print("; aggressivity:" + this.aggressivity);
        System.out.println("; defencivity:" + this.defencivity);
    }
}

public class Caretaker
{
    private Memento memento;

    public Memento getMemento()
    {
        return memento;
    }

    public void setMemento(final Memento memento)
    {
        this.memento = memento;
    }
}

public class Client
{
    public static void main(final String[] args)
    {
        final PlayerOriginator player = new PlayerOriginator(100, 100, 100);
        System.out.print("player's original attributes are ");
        player.showState();

        final Caretaker taker = new Caretaker();
        taker.setMemento(player.createMemento());

        player.setVitality(70);
        player.setAggressivity(60);
        player.setDefencivity(20);

        System.out.print("after player fight with Boss, player's attributes are ");
        player.showState();

        //reset player's attribute
        player.setMemento(taker.getMemento());
        System.out.print("after resetting, player's attributes are ");
        player.showState();

    }

}

结果:
player's original attributes are vitality:100; aggressivity:100; defencivity:100
after player fight with Boss, player's attributes are vitality:70; aggressivity:60; defencivity:20
after resetting, player's attributes are vitality:100; aggressivity:100; defencivity:100