1. 游戏存进度

B: 代码无错未必优。
A: 问题主要在于这客户端的调用。应为这样写就把整个游戏角色的细节暴露给了客户端,你客户端职责就太大了。
A: 显然,游戏角色的存取细节封装起来,而且最好封装在外部的类当中。以体现职责分离。

2. 备忘录模式

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

图1
B: 如果我们不需要保存全部的信息?
A: 只是部分,那么就应该有一个独立的备忘录类Memento,它只拥有需要保存的信息的属性。

3. 备忘录基本代码

class Program
{
    static void Main(string[] args)
    {

        Originator o = new Originator();
        o.State = "On";
        o.Show();

        Caretaker c = new Caretaker();
        c.Memento = o.CreateMemento();

        o.State = "Off";
        o.Show();

        o.SetMemento(c.Memento);
        o.Show();

        Console.Read();

    }
}

class Originator
{
    private string state;
    public string State
    {
        get { return state; }
        set { state = value; }
    }

    public Memento CreateMemento()
    {
        return (new Memento(state));
    }

    public void SetMemento(Memento memento)
    {
        state = memento.State;
    }

    public void Show()
    {
        Console.WriteLine("State=" + state);
    }
}

class Memento
{
    private string state;

    public Memento(string state)
    {
        this.state = state;
    }

    public string State
    {
        get { return state; }
    }
}

class Caretaker
{
    private Memento memento;

    public Memento Memento
    {
        get { return memento; }
        set { memento = value; }
    }
}

B: 就是把保存的细节封装在了Memento了,哪一天要更改保存的细节也不用影响客服端了。
A: Memento模式比较适合于功能比较复杂的,但需要维护或记录属性历史的类,或者需要保存的属性只是众多属性中的一小部分,Origniator可以根据保存的Memento信息还原到前以状态。
A: 如果在某个系统中使用命令模式,需要实现命令的撤销功能,那么命令模式可以使用备忘录模式来存储可撤销操作的状态。保存在对象以外的地方,但是必须有对象自己读取,这时,使用备忘录可以把复杂的对象内部信息对其他的对象屏蔽起来,从而可以恰当的保持封装的边界。
B: 当角色的状态改变的时候,有可能这个状态无效,这时候就可以使用暂时存储起来的备忘录将状态复原。

4. 游戏进度备忘

图2

class Program
{
    static void Main(string[] args)
    {

        //大战Boss前
        GameRole lixiaoyao = new GameRole();
        lixiaoyao.GetInitState();
        lixiaoyao.StateDisplay();

        //保存进度
        RoleStateCaretaker stateAdmin = new RoleStateCaretaker();
        stateAdmin.Memento = lixiaoyao.SaveState();

        //大战Boss时,损耗严重
        lixiaoyao.Fight();
        lixiaoyao.StateDisplay();

        //恢复之前状态
        lixiaoyao.RecoveryState(stateAdmin.Memento);

        lixiaoyao.StateDisplay();


        Console.Read();

    }
}

class GameRole
{
    //生命力
    private int vit;
    public int Vitality
    {
        get { return vit; }
        set { vit = value; }
    }

    //攻击力
    private int atk;
    public int Attack
    {
        get { return atk; }
        set { atk = value; }
    }

    //防御力
    private int def;
    public int Defense
    {
        get { return def; }
        set { def = value; }
    }

    //状态显示
    public void StateDisplay()
    {
        Console.WriteLine("角色当前状态:");
        Console.WriteLine("体力:{0}", this.vit);
        Console.WriteLine("攻击力:{0}", this.atk);
        Console.WriteLine("防御力:{0}", this.def);
        Console.WriteLine("");
    }

    //保存角色状态
    public RoleStateMemento SaveState()
    {
        return (new RoleStateMemento(vit, atk, def));
    }

    //恢复角色状态
    public void RecoveryState(RoleStateMemento memento)
    {
        this.vit = memento.Vitality;
        this.atk = memento.Attack;
        this.def = memento.Defense;
    }


    //获得初始状态
    public void GetInitState()
    {
        this.vit = 100;
        this.atk = 100;
        this.def = 100;
    }

    //战斗
    public void Fight()
    {
        this.vit = 0;
        this.atk = 0;
        this.def = 0;
    }
}

//角色状态存储箱
class RoleStateMemento
{
    private int vit;
    private int atk;
    private int def;

    public RoleStateMemento(int vit, int atk, int def)
    {
        this.vit = vit;
        this.atk = atk;
        this.def = def;
    }

    //生命力
    public int Vitality
    {
        get { return vit; }
        set { vit = value; }
    }

    //攻击力
    public int Attack
    {
        get { return atk; }
        set { atk = value; }
    }

    //防御力
    public int Defense
    {
        get { return def; }
        set { def = value; }
    }
}

//角色状态管理者
class RoleStateCaretaker
{
    private RoleStateMemento memento;

    public RoleStateMemento Memento
    {
        get { return memento; }
        set { memento = value; }
    }
}

A: 如果状态数据很大很多,那么在资源的消耗上,备忘录对象会非常耗内存。


yuanoung
10 声望1 粉丝

« 上一篇
适配器模式
下一篇 »
组合模式

引用和评论

0 条评论