状态模式是一种行为设计模式,它允许对象在其内部状态改变时改变其行为,我们可以通过创建一个状态接口和一些实现了该接口的状态类来实现状态模式。然后,我们可以创建一个上下文类,它会根据其当前的状态对象来改变其行为。
抽象状态
public interface IState
{
void Handle(Context context);
}
具体状态
ConcreteStateA和ConcreteStateB,它们都实现了IState接口。
IState接口定义了一个Handle方法,这个方法接受一个Context对象作为参数。Context对象持有当前的状态。
在ConcreteStateA的Handle方法中,它将Context的状态改变为ConcreteStateB。同样,在ConcreteStateB的Handle方法中,它将Context的状态改变为ConcreteStateA。
这样,Context对象的状态就在ConcreteStateA和ConcreteStateB之间不断切换。
这就是状态模式的基本思想:当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
public class ConcreteStateA : IState
{
public void Handle(Context context)
{
context.State = new ConcreteStateB();
}
}
public class ConcreteStateB : IState
{
public void Handle(Context context)
{
context.State = new ConcreteStateA();
}
}
环境角色
环境角色有时候也被称为上下文角色,它定义了客户端需要的接口,并且维护一个具体状态角色的实例,这个实例定义当前状态。
在这个类中,首先定义了一个私有的IState类型的_state变量,用于存储当前的状态。
然后,定义了一个构造函数,接收一个IState类型的参数,用于初始化_state变量。
接着,定义了一个公有的State属性,用于获取或设置_state变量的值。在设置_state变量的值时,会输出当前状态的类型名。
最后,定义了一个名为Request的方法,该方法会调用_state变量的Handle方法,用于处理请求。这个方法的参数是当前的Context实例,这样就可以在Handle方法中改变当前的状态。
public class Context
{
private IState _state;
// Constructor
public Context(IState state)
{
this.State = state;
}
// Gets or sets the state
public IState State
{
get { return _state; }
set
{
_state = value;
Console.WriteLine("State: " + _state.GetType().Name);
}
}
public void Request()
{
_state.Handle(this);
}
}
测试
class MyClass
{
public static void Main(string[] args)
{
Context context = new Context(new ConcreteStateA());
// 不断地进行请求,同时更改状态
context.Request();
context.Request();
context.Request();
context.Request();
}
}
运行结果:
在测试类中,我们创建了一个Context
对象,并给它设置了初始状态ConcreteStateA
。然后我们连续调用四次context.Request()
方法。由于ConcreteStateA
和ConcreteStateB
在处理请求后会互相转换,所以输出结果会是A、B、A、B的交替出现。
使用场景: