定义
允许一个对象在其状态改变时,改变它的行为。看起来对象似乎修改了它的类。
解决问题
State模式主要解决的是在开发中时常遇到的根据不同的状态需要进行不同的处理操作的问题。解决这种问题,最一般的方法是采用switch-case语句进 行处理的,这样会造成一个问题:分支过多,而且如果加入一个新的状态就需要对原来的代码进行编译。
State模式采用了对这些不同的状态进行封装的方式处 理这类问题,当状态改变的时候进行处理然后再切换到另一种状态,也就是说把状态的切换责任交给了具体的状态类去负责.
State模式与Strategy模式比较:
State模式和 Strategy模式有很多相似的地方,需要说明的是两者的思想都是一致的,只不过封装的东西不同:State模式封装的是不同的状态,而Stategy 模式封装的是不同的算法。
涉及的角色
上下文对象:定义了当前状态,并能根据请求改变当前的状态。
抽象状态:定义了一个封装上下文特定状态切换的接口
具体状态:每一个具体状态实现特定的状态切换方法。
状态模式的关键:不同状态所具有的行为接口相同。
类图
实现代码
namespace Hbb0b0.DesignPatter
public class StateContext
private AbstractState state; public AbstractState State
public StateContext(AbstractState state)
this.State = state;
public void Request()
public abstract class AbstractState
abstract public void Handle(StateContext context);
public class ConcreteStateA : AbstractState
public override void Handle(StateContext context)
public class ConcreteStateB : AbstractState
public override void Handle(StateContext context)
public class ConcreteStateC : AbstractState
public override void Handle(StateContext context)
StateContext stateContext = new StateContext(new ConcreteStateA ()); //上下文请求状态改变
stateContext.Request(); //上下文请求状态改变
stateContext.Request(); //上下文请求状态改变
stateContext.Request(); //上下文请求状态改变
stateContext.Request(); //上下文请求状态改变
stateContext.Request();
{
/// <summary> /// 上下文对象 /// </summary>public class StateContext
{
/// <summary> /// 状态 /// </summary>private AbstractState state; public AbstractState State
{
get { return state; } set {state
= value;Console.WriteLine(
"State: " + state.GetType().Name);}
}
/// <summary> /// 上下文构造函数 /// </summary> /// <param name="state"></param>public StateContext(AbstractState state)
{
//注意不要用this.state=state,如果写成这样就不会触发状态改变的 //控制台输出this.State = state;
}
/// <summary> /// 请求改变状态 /// </summary>public void Request()
{
state.Handle(
this);}
}
}
namespace Hbb0b0.DesignPatter{
/// <summary> /// 抽象状态 /// </summary>public abstract class AbstractState
{
/// <summary> /// 状态切换 /// </summary> /// <param name="context">上下文对象</param>abstract public void Handle(StateContext context);
}
}
namespace Hbb0b0.DesignPatter{
/// <summary> /// 具体状态B /// </summary>public class ConcreteStateA : AbstractState
{
/// <summary> /// 具体状态切换A-->B /// </summary> /// <param name="context">上下文对象</param>public override void Handle(StateContext context)
{
context.State
= new ConcreteStateB();}
}
}
namespace Hbb0b0.DesignPatter{
/// <summary> /// 状态B /// </summary>public class ConcreteStateB : AbstractState
{
/// <summary> /// 具体状态切换B-->C /// </summary> /// <param name="context">上下文对象</param>public override void Handle(StateContext context)
{
context.State
= new ConcreteStateC();}
}
}
namespace Hbb0b0.DesignPatter{
/// <summary> /// 状态C /// </summary>public class ConcreteStateC : AbstractState
{
/// <summary> /// 具体状态切换B-->C /// </summary> /// <param name="context">上下文对象</param>public override void Handle(StateContext context)
{
context.State
= new ConcreteStateA();}
}
}
调用代码
{
class StateMain{
static internal void Run(){
//用A状态初始化上下文StateContext stateContext = new StateContext(new ConcreteStateA ()); //上下文请求状态改变
stateContext.Request(); //上下文请求状态改变
stateContext.Request(); //上下文请求状态改变
stateContext.Request(); //上下文请求状态改变
stateContext.Request(); //上下文请求状态改变
stateContext.Request();
}
}
}
运行结果
思考:以上类中添加了状态D,如何实现?
类图如下
具体的实现代码就不写了,当具体的环境中添加了新状态ConcreteStateD, ConcreteStateE, ConcreteStateF时,由现有的类关系图可以体会出使用State模式的强大功能。