3.2.1 模式意图:
根据对象内部状态的不同,而产生的不同行为,常规会直接采用
if else
语句,但是随着状态的增多,常规方式多会造成系统耦合度的增加,bug出现几率升高,当遇到这类情况时,可以使用状态模式进行重构。
3.2.2 模式概念:
它属于行为型模式,允许一个对象在其内部状态改变时改变它的行为,对象看起来似乎修改了它的类。
3.2.3 模式元素:
- 上下文(Context)
- 状态类抽象(State)
- 状态类细节(ConcreteStateA、ConcreteStateB等)
3.2.4 代码示例:
A.状态相关
public abstract class State
{
protected Context context = null;
public State(Context context)
{
this.context = context;
}
public abstract void Handle(string value);
}
public class ConcreteStateA : State
{
public ConcreteStateA(Context context) : base(context)
{ }
public override void Handle(string value)
{
Debug.Log("ConcreteStateA.Handle");
if (value == "喜")
context.SetState(new ConcreteStateB(context));
}
}
public class ConcreteStateB : State
{
public ConcreteStateB(Context context) : base(context)
{ }
public override void Handle(string value)
{
Debug.Log("ConcreteStateB.Handle");
if (value == "喜")
context.SetState(new ConcreteStateC(context));
}
}
public class ConcreteStateC : State
{
public ConcreteStateC(Context context) : base(context)
{ }
public override void Handle(string value)
{
Debug.Log("ConcreteStateC.Handle");
if (value == "喜")
context.SetState(new ConcreteStateA(context));
}
}
public class ConcreteStateD : State
{
public ConcreteStateD(Context context) : base(context)
{ }
public override void Handle(string value)
{
Debug.Log("ConcreteStateC.Handle");
if (value == "乐")
context.SetState(new ConcreteStateA(context));
}
}
B.上下文
public class Context
{
State state = null;
public void Change(string value)
{
state.Handle(value);
}
public void SetState(State theState)
{
state = theState;
}
}
示例代码调用
void UnitTest()
{
Context context = new Context();
context.SetState(new ConcreteStateA(context));
context.Change("喜");
context.Change("怒");
context.Change("哀");
context.Change("乐");
}
打印日志
3.2.5 写法对比:
略
3.2.6 模式分析:
状态模式简化了多状态切换时使用的
if elseif
语句,将对应的跳转条件与状态行为分别分散到不同的子类中。而且对应状态的添加和删减会更加容易,只需要定义新的子类即可。这种状态逻辑和跳转的隔离,减少了相互的依赖与干扰。对于状态的复用有一定的帮助。但也要关注状态子类的个数,避免状态因子类过多而造成调试上的困难。
3.2.7 应用场景:
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式。
3.2.8 小结:
在开发中一般会在有限状态机中看到状态模式的身影,这也是在实际开发中使用频率不多但针对性很强的设计模式。