状态模式(State),当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象的状态转换的条件表达式过于复杂时的情况,把状态判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。如果状态判断很简单,就没有必要用‘状态模式’了
状态模式结构图
State类,抽象状态类,定义一个接口以封装与Context的一个特定状态的行为。
abstract class State
{
public abstract void Handle(Context context);
}
ConcreteState类,具体状态,每一个子类实现一个与Context的一个状态相关的行为。
class ConcreteStateA : State
{
public override void Handle(Context context)
{
context.State = new ConcreteStateB();
}
}
class ConcreteStateB : State
{
public override void Handle(Context context)
{
context.State = new ConcreteStateA();
}
}
Context类,维护一个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);
}
}
---客户端代码---
static void Main(string[] args)
{
//设置Context的初始状态为 concreteStateA
Context c = new Context(new concreteStateA());
//不断的请求,同时更改状态
c.Request();
c.Request();
c.Request();
c.Request();
c.Request();
Console.Read();
}
状态模式的好处是将特定状态相关的行为局部化,并且将不同状态的行为分割开来。
目的就是消除庞大的条件分支语句,状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。
工作状态的代码结构图:
工作状态的代码实现
抽象状态
public abstract class State
{
public abstract void WriteProgram(Work w);
}
上午和中午工作状态类
public class ForenoonState : State
{
public override void WriteProgram(Wrok w)
{
if(w.Hour <12)
{
Console.WriteLine("当前时间:{0}点,上午工作,精神百倍",w.Hor
}
else
{
w.SetState(new NoonState());
w.WriteProgram();
}
}
}
中午工作状态类
public class NoonState : State
{
public override void WriteProgram(Wrok w)
{
if(w.Hour <13)
{
Console.WriteLine("当前时间:{0}点,饿了,犯困,午休",w.Hor
}
else
{
//转入到下午工作状态
w.SetState(new AfterNoonState());
w.WriteProgram();
}
}
}
//此时工作类,没有了过长的分支判断语句
public class Work
{
private State current;
public Work()
{
current = new ForenoonState();
}
private double hour
public double Hour
{
get { return hour;}
set { hour = value;}
}
public void SetState(State s)
{
current = s;
}
public void WriteProgram()
{
current.WriteProgram(this);
}
}
---客户端代码---
static void Main(string[] args)
{
Work p1 = new Work();
p1.Hour = 12;
p1.WriteProgram();
p1.Hour = 13;
p1.WriteProgram();
Consele.Read();
}