-
21. State 状态模式
2008-09-22
- 动机(Motivation)
- 在软件构建过程中,某些对象的状态如果改变,其行为也会随之而发生变化,比如文档处于只读状态,其支持的行为和读写状态支持的行为就可能完全不同。
- 如何在运行时根据对象的状态来透明地更改对象的行为?而不会为对象操作和状态转化之间引入紧耦合?
- 意图(Intent)
- 允许一个对象在其内部状态改变时改变它的行为。从而使对象看起来似乎修改了其行为。 ——《设计模式》GoF
基本代码:
//抽象状态类,定义一个接口以封装与Context的一个特定状态相关的行为
abstract class State
{
public abstract void Handle(Context context);
}
abstract class State
{
public abstract void Handle(Context context);
}
//具体状态,每一个子类实现一个与Context的一个状态相关的行为
class ConcreteStateA : State
{
public override void Handle(Context context)
{
//设置ConcreteStateA的下一个状态是ConcreteStateB
context.State = new ConcreteStateB();
}
}
class ConcreteStateA : State
{
public override void Handle(Context context)
{
//设置ConcreteStateA的下一个状态是ConcreteStateB
context.State = new ConcreteStateB();
}
}
-
class ConcreteStateB : State
{
public override void Handle(Context context)
{
context.State = new ConcreteStateA();
}
} -
-
//维护一个ConcreteState子类的实例,用于定义当前的状态
class Context
{
private State state;
public Context(State state)
{
this.state = state;
}
public State State
{
get { return state; }
set
{
state = value;
Console.WriteLine("当前状态:" + state.GetType().Name);
}
}
public void Request()
{
state.Handle(this);
}
} -
-
客户端代码:class Program
{
static void Main(string[] args)
{
//设置Context的初始状态为ConcreteStateA
Context c = new Context(new ConcreteStateA());
//不断的请求,同时更改状态
c.Request();
c.Request();
c.Request();
c.Request();
Console.Read();
}
} -
-
State的几个要点:
State模式将所有与一个特定状态相关的行为都放入一个State的子类对象中,在对象状态切换时,切换相应的对象;但同时维持State的接口,这样实现了具体操作与状态转换之间的解耦。
为不同的状态引入不同的对象使得状态转换变得更加明确,而且可以保证不会出现状态不一致的情况,因为转换是原子性的——即要么彻底转换过来,要么不转换。
如果State对象没有实例变量,那么各个上下文可以共享同一个State对象,从而节省对象开销。
作者:MaoBisheng
出处:http://maobisheng.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
出处:http://maobisheng.cnblogs.com/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。