状态模式(State)定义:当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。
什么是状态:
应用程序中的部分对象可能会根据不同的情况做出不同的行为,我们把这种对象称为有状态的对象,而把影响对象行为的一个或多个动态变化的属性称为状态
优点:
- 将与特定状态相关的行为放到该状态中,并且将不同状态下的行为分割开来,消除了选择语句,满足“单一职责原则”
- 将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。
- 状态类职责明确,有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。
缺点:
- 必然会增加系统的类与对象的个数。
- 结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。
- 不利于实现开闭原则,对于可以切换状态的状态模式,增加新的状态类需要修改那些负- 责状态转换的源码,否则无法切换到新增状态,而且修改某个状态类的行为也需要修改对应类的源码。
模式的结构
- 环境类(Context)角色:也称为上下文,它定义了客户端需要的接口,内部维护一个当前状态,并负责具体状态的切换。
- 抽象状态(State)角色:定义一个接口,用以封装环境对象中的特定状态所对应的行为,可以有一个或多个行为。
- 具体状态(Concrete State)角色:实现抽象状态所对应的行为,并且在需要的情况下进行状态切换。
代码背景:打工人从早到晚打工的精神状态。
抽象状态类:
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();//超过21点,转入睡眠状态
}
}
}
}
//睡眠状态
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(); //初始化为上午9点开始上班
}
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);
}
}
客户端:
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.TaskFinished = false;//未完成任务,加班
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 19;
emergencyProjects.WriteProgram();
emergencyProjects.Hour = 22;
emergencyProjects.WriteProgram();
Console.Read();
}
扫描二维码关注公众号,回复:
12559215 查看本文章