Unity多媒体互动开发,Unity最新技术学习

设计模式与游戏完美开发学习--状态模式(概念篇)

前言

  既然是要学习设计模式,肯定得知道啥是设计模式,又有啥用?设计模式是啥?笔者我也不是特别,只听同道中人天天说。笔者自己的理解就是为了解决某一个问题(软件问题)而归纳总结出来的一套解决方案(软件模式),而这套方案对以后出现的同样或类似接近的问题同样适用。个人觉得只要理解就好。哈哈哈!!!咱们进入今天的正题:设计模式之状态模式。

状态模式的概念

  又要解释概念,好烦哦!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来变现不同行为并转换状态。执行结果如下:

总结

  状态设计模式就介绍到这为止,下一篇我们做一个简单的应用案例。笔者也是刚刚学习,如有解释不到的地方还请见谅。对于编程这块,个人认为还是要多加应用才能理解更深。

参考

<<设计模式与游戏完美开发>>

如有侵权,请联系删除!

-------------本文结束感谢您的阅读-------------