您的位置:首页 > 移动开发 > Unity3D

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

2017-01-16 17:02 936 查看
 
 这次来说说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。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Unity 设计模式