前言
既然是要学习设计模式,肯定得知道啥是设计模式,又有啥用?设计模式是啥?笔者我也不是特别,只听同道中人天天说。笔者自己的理解就是为了解决某一个问题(软件问题)而归纳总结出来的一套解决方案(软件模式),而这套方案对以后出现的同样或类似接近的问题同样适用。个人觉得只要理解就好。哈哈哈!!!咱们进入今天的正题:设计模式之状态模式。
状态模式的概念
又要解释概念,好烦哦!GoF定义:让一个对象的行为随着内部状态的改变而改变,而该对象就像换了一个类一样(怎么觉得好像C++的多态)。个人理解就是一个对象对不同的状态做出不同的行为。还请指教!!!
状态模式的说明
既然已经知道了什么是状态模式,那怎么去实现呢?在实现之前,我们来先了解一下状态模式的结构。既然是状态模式,那肯定要有一个描述状态的类(State),而根据定义”…随着内部状态的改变…”,那肯定不止一个状态,因此我们需要将State类作为基类去具体定义不同具体的状态类(ConcreteState),再看定义”让一个对象…”,因此我们还需要一个状态拥有者的类(Context),去对不同的状态做出不同的行为。具体结构图如下:
说明如下:
Context: 状态拥有者,拥有状态属性,主要完成让外界得知状态的改变或者操作状态改变。
State: 状态的基类,指定状态的接口,负责规范状态拥有者要表现的行为。
ConcreteState: 具体的状态类,拥有特定状态下的行为,是状态的细化。
状态模式的实现
根据以上对状态模式的分析,下面我们来做类的设计实现,首先是State基类:
1 2 3 4 5 6 7 8 9 10 11 12
| // 状态接口类 public abstract class State { protected Context m_Context = null; public State(Context theContext) { m_Context = theContext; }
public abstract void Handle(int value); }
|
声明一个Context对象,并作为State生成对象时传入的参数,以便State拥有Context,可以后续操作Context对象。定义抽象方法Handle,便于子类呈现不同的行为。
再定义一个Context类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| // 状态拥有者 public class Context { private State m_State = null;
public void Request(int value) { m_State.Handle(value); }
public void SetState(State theState) { Debug.Log("Context.SetState : " + theState); m_State = theState; } }
|
Context类拥有State属性,可以通过Request来呈现当前状态的行为,通过SetState方法设置当前状态。
最后定义三个具体的状态:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| public class ConcreteStateA : State { public ConcreteStateA(Context theContext) : base(theContext) { }
public override void Handle(int value) { Debug.Log("ConcreteStateA.Handle"); if(value > 10) { m_Context.SetState(new ConcreteStateB(m_Context)); } } }
public class ConcreteStateB : State { public ConcreteStateB(Context theContext) : base(theContext) { }
public override void Handle(int value) { Debug.Log("ConcreteStateB.Handle"); if (value > 20) { m_Context.SetState(new ConcreteStateC(m_Context)); } } }
public class ConcreteStateC : State { public ConcreteStateC(Context theContext) : base(theContext) { }
public override void Handle(int value) { Debug.Log("ConcreteStateC.Handle"); if (value > 30) { m_Context.SetState(new ConcreteStateA(m_Context)); } } }
|
三个子类分别实现了Handle方法来表现各自的行为。然后根据判定条件来通知Context(状态拥有者)状态发生改变。
下面我们来编写测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13
| public class TestState : MonoBehaviour { void Start() { Context context = new Context(); context.SetState(new ConcreteStateA(context)); context.Request(5); context.Request(15); context.Request(25); context.Request(35); } }
|
首先生成一个Context对象,然后设置状态为ConcreteStateA,再调用Request来变现不同行为并转换状态。执行结果如下:
总结
状态设计模式就介绍到这为止,下一篇我们做一个简单的应用案例。笔者也是刚刚学习,如有解释不到的地方还请见谅。对于编程这块,个人认为还是要多加应用才能理解更深。
参考
<<设计模式与游戏完美开发>>
如有侵权,请联系删除!