设计模式深入学习--State 状态模式(行为型模式)

   这次来说说State状态模式,State状态模式用于我们在编程开发中大量用到 if Else的情况下,有很多分支的判断那么用状态模式就最好不过了,如在AI设计中的状态机就可以用State状态模式来设计一个AI机器人。 我们先来看看State状态模式的基本代码。

//抽象状态类 定义一个接口以封装与Context的一个特定状态相关的行为
 
abstract class State
{
    public abstract void Handle(Context context);
}
 
class ConcreteStateA : State
{
    public override void Handle(Context context)
    {
        context.State=new ConcreteStateB();
    }
}
 
 class ConcreteStateB : State
{
    public override void Handle(Context context)
    {
        context.State = new ConcreteStateA();
    }
}
 
 
 
class Context
{
    private State state;
 
    public Context(State state)
    {
        this.state = state;
    }
 
    public State State
    {
        get { return state; }
        set
        {
            state = value;
            Console.WriteLine("当前状态:"+state.GetType().Name);
        }
    }
 
    public void Request()
    {
        state.Handle(this);
    }
 
}
   总的来说,这个设计模式其实很简单,一个发起人类,一个备忘录类,一个管理者类,发起人类就是我们客户端需要记录状态的类,备忘录类就保存我们需要记录的数据类,管理者类作为一个调用者。再看看运行代码:

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();


            首先实现一个发起人 Originator类,然后设定状态为 On, 然后实现管理者类,然后在发起人中保存状态到管理者类,再改变状态为Off,输出为Off,然后恢复,在输出,状态又变回On了。是不是很简单,清晰呢,下面我们再来做个类似的游戏例子,模拟我们在游戏中的开发,读档存档功能。

class GamePlayer
{
    private int hp;
    private int mp;
    private int atk;
 
    public int Hp
    {
        get { return hp; }
        set { hp = value; }
    }
    public int Mp
    {
        get { return mp; }
        set { mp = value; }
    }
    public int Attack
    {
        get { return atk; }
        set { atk = value; }
    }
 
    public void ShowState()
    {
        Console.WriteLine("生命值:" + Hp);
        Console.WriteLine("魔法值:" + Mp);
        Console.WriteLine("攻击力:" + Attack);
    }
 
    //设置初始值
    public void Init()
    {
        Hp = 100;
        Mp = 100;
        Attack = 100;
    }
 
 
 
    public void InBattle()
    {
        Random rd=new Random();
        Hp = rd.Next(0, 20);
        Mp = rd.Next(0, 20);
        Attack = rd.Next(0, 20);
    }
 
    //保存进度
    public PlayerMemento SavePlayerState()
    {
        return (new PlayerMemento(Hp, Mp, Attack));
    }
 
    //恢复进度
    public void RecoveryPlayerState(PlayerMemento memento)
    {
        this.Hp = memento.Hp;
        this.Mp = memento.Mp;
        this.Attack = memento.Attack;
    }
 
}
 
 
 
//备忘录
class PlayerMemento
{
    private int hp;
    private int mp;
    private int atk;
    public int Hp
    {
        get { return hp; }
        set { hp = value; }
    }
    public int Mp
    {
        get { return mp; }
        set { mp = value; }
    }
    public int Attack
    {
        get { return atk; }
        set { atk = value; }
    }
 
    public PlayerMemento(int hp, int mp, int atk)
    {
        this.hp = hp;
        this.mp = mp;
        this.atk = atk;
 
    }
 
 
}
 
 
//管理者
class PlayerStateCaretaker
{
 
    private PlayerMemento memento;
 
    public PlayerMemento Menento
    {
        get { return memento; }
        set { memento = value; }
    }
}

            首先还是做3个类,一个玩家类GamePlayer ,存放玩家需要保存的信息类,一个备忘录类PlayerMemento,存放数据,一个管理者类PlayerStateCaretaker,给外部调用。 然后就是运行的代码:

GamePlayer 赵日天=new GamePlayer();
           赵日天.Init();
           赵日天.ShowState();
           Console.WriteLine("保存好进度,开始下副本");
           //保存进度
           PlayerStateCaretaker stateCaretaker=new PlayerStateCaretaker();
           stateCaretaker.Menento = 赵日天.SavePlayerState();
         
           //打怪消耗
           赵日天.InBattle();
           赵日天.ShowState();
           Console.WriteLine("状态不行,还是回档吧");
           //重新读档
           赵日天.RecoveryPlayerState(stateCaretaker.Menento);
           赵日天.ShowState();
   首先声明玩家类和管理者类,然后玩家类初始化完成,保存信息后开始下副本,输出结果,各项数值消耗了,然后回档,管理者重新把备忘录的数据传回玩家类

 

   再来总结下,备忘录模式应用分析
  备忘录模式适用情形:
  1、必须保存一个对象在某一个时刻的部分状态,这样以后需要时才能恢复到先前的状态。
  2、如果用一个接口来让其他对象直接得到被保存对象的内部状态,将会暴露对象的实现细节并破坏对象的封装性。
  备忘录模式特点:
  1、保持封装边界。使用备忘录可以避免暴露一些只应由Originator管理却又必须存储在Originator之外的信息。该模式把可能很复杂的Originator内部信息对其他对象屏蔽起来,从而保持了封装边界。
  2、简化Originator。在其他的保持封装性的设计中,Originator负责保持Client请求过的内部状态版本。把所存储管理的重任交给了Originator,让Client管理它们请求的状态将会简化Originator,并使得Client工作结束时无需通知Originator。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值