一,概述
状态模式:允许对象在内部状态改变时改变它的行为,对象看起来好像修改了它的类。
状态模式主要解决的是当控制一个对象状态的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类中,可以把复杂的判断逻辑简化。
意图:允许一个对象在其内部状态改变时改变它的行为
适用场景:
1.一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为。
2.一个操作中含有庞大的多分支结构,并且这些分支决定于对象的状态。
二,示例
题目:根据不同时间段,显示不同时间段的精神状态
1)面向过程版本
class Program
{
static int Hour = 0;
static bool WorkFinished = false;
static void Main(string[] args)
{
Hour = 9;
WriteProgram();
Hour = 10;
WriteProgram();
Hour = 12;
WriteProgram();
Hour = 13;
WriteProgram();
Hour = 14;
WriteProgram();
Hour = 17;
WorkFinished = true;
//WorkFinished = false;
WriteProgram();
Hour = 19;
WriteProgram();
Hour = 22;
WriteProgram();
Console.Read();
}
public static void WriteProgram()
{
if (Hour < 12)
{
Console.WriteLine("当前时间:{0}点 上午工作,精神百倍", Hour);
}
else if (Hour < 13)
{
Console.WriteLine("当前时间:{0}点 饿了,午饭;犯困,午休。", Hour);
}
else if (Hour < 17)
{
Console.WriteLine("当前时间:{0}点 下午状态还不错,继续努力", Hour);
}
else
{
if (WorkFinished)
{
Console.WriteLine("当前时间:{0}点 下班回家了", Hour);
}
else
{
if (Hour < 21)
{
Console.WriteLine("当前时间:{0}点 加班哦,疲累之极", Hour);
}
else
{
Console.WriteLine("当前时间:{0}点 不行了,睡着了。", Hour);
}
}
}
}
}
2)工作状态分类版本
缺点:WriteProgram 中有太多的判断,如果更改时间段可能要改好几个,而且改错的风险极大
class Program
{
static void Main(string[] args) //通过类设置不同hour 从而打印不同状态
{
//紧急项目
Work emergencyProjects = new Work();
emergencyProjects.Hour = 9;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 10;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 12;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 13;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 14;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 17;
//emergencyProjects.WorkFinished = true;
emergencyProjects.TaskFinished = false;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 19;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 22;
emergencyProjects.WriteProgram();
Console.Read();
}
}
//工作
public class Work
{
//钟点
private int hour;
public int Hour
{
get { return hour; }
set { hour = value; }
}
//任务完成
private bool finish = false;
public bool TaskFinished
{
get { return finish; }
set { finish = value; }
}
public void WriteProgram()
{
if (hour < 12)
{
Console.WriteLine("当前时间:{0}点 上午工作,精神百倍", hour);
}
else if (hour < 13)
{
Console.WriteLine("当前时间:{0}点 饿了,午饭;犯困,午休。", hour);
}
else if (hour < 17)
{
Console.WriteLine("当前时间:{0}点 下午状态还不错,继续努力", hour);
}
else
{
if (finish)
{
Console.WriteLine("当前时间:{0}点 下班回家了", hour);
}
else
{
if (hour < 21)
{
Console.WriteLine("当前时间:{0}点 加班哦,疲累之极", hour);
}
else
{
Console.WriteLine("当前时间:{0}点 不行了,睡着了。", hour);
}
}
}
}
}
3)状态模式
主要解决的问题:当控制一个对象状态转移的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中。可以把复杂的逻辑简化。
优点:将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
消除庞大的条件分支语句。
class Program
{
static void Main(string[] args)
{
//紧急项目
Work emergencyProjects = new Work();
emergencyProjects.Hour = 9;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 10;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 12;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 13;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 14;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 17;
//emergencyProjects.WorkFinished = true;
emergencyProjects.TaskFinished = false;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 19;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 22;
emergencyProjects.WriteProgram();
Console.Read();
}
}
//抽象状态
public abstract class State
{
public abstract void WriteProgram(Work w);
}
//上午工作状态
public class ForenoonState : State
{
public override void WriteProgram(Work w)
{
if (w.Hour < 12)
{
Console.WriteLine("当前时间:{0}点 上午工作,精神百倍", w.Hour);
}
else
{
w.SetState(new NoonState());
w.WriteProgram();
}
}
}
//中午工作状态
public class NoonState : State
{
public override void WriteProgram(Work w)
{
if (w.Hour < 13)
{
Console.WriteLine("当前时间:{0}点 饿了,午饭;犯困,午休。", w.Hour);
}
else
{
w.SetState(new AfternoonState());
w.WriteProgram();
}
}
}
//下午工作状态
public class AfternoonState : State
{
public override void WriteProgram(Work w)
{
if (w.Hour < 17)
{
Console.WriteLine("当前时间:{0}点 下午状态还不错,继续努力", w.Hour);
}
else
{
w.SetState(new EveningState());
w.WriteProgram();
}
}
}
//晚间工作状态
public class EveningState : State
{
public override void WriteProgram(Work w)
{
if (w.TaskFinished)
{
w.SetState(new RestState());
w.WriteProgram();
}
else
{
if (w.Hour < 21)
{
Console.WriteLine("当前时间:{0}点 加班哦,疲累之极", w.Hour);
}
else
{
w.SetState(new SleepingState());
w.WriteProgram();
}
}
}
}
//睡眠状态
public class SleepingState : State
{
public override void WriteProgram(Work w)
{
Console.WriteLine("当前时间:{0}点 不行了,睡着了。", w.Hour);
}
}
//下班休息状态
public class RestState : State
{
public override void WriteProgram(Work w)
{
Console.WriteLine("当前时间:{0}点 下班回家了", w.Hour);
}
}
//工作
public class Work
{
private State current;
public Work()
{
current = new ForenoonState();
}
private double hour;
public double Hour
{
get { return hour; }
set { hour = value; }
}
private bool finish = false;
public bool TaskFinished
{
get { return finish; }
set { finish = value; }
}
public void SetState(State s)
{
current = s;
}
public void WriteProgram()
{
current.WriteProgram(this);
}
}
三,状态模式模板
class Program
{
static void Main(string[] args)
{
Context c = new Context(new ConcreteStateA());
c.Request();
c.Request();
c.Request();
c.Request();
Console.Read();
}
}
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);
}
}
abstract class State
{
public abstract void Handle(Context 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();
}
}