定 义:当一个对象内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况,
把状态的判断逻辑转移到表示不同状态的一系列子类中,可以把复杂的逻辑简化。
结构图:
示例结构图:
状态类:
//抽象状态 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()); //超过12点转入中午工作状态 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()); //超过13点转入下午工作状态 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()); //超过17点转入傍晚工作状态 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()); //超过21点,则转入睡眠状态 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(); //工作初始化为上午工作状态,即上午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); } }
客户端调用:
Work w = new Work(); w.Hour = 9; w.WriteProgram(); w.Hour = 10; w.WriteProgram(); w.Hour = 12; w.WriteProgram(); w.Hour = 13; w.WriteProgram(); w.Hour = 14; w.WriteProgram(); w.Hour = 17; w.TaskFinished =true; w.WriteProgram(); w.Hour = 19; w.WriteProgram(); w.Hour = 22; w.WriteProgram(); #endregion
优点和缺点:
优点:将与特定相关的行为局部化,并且将不同状态的行为分割开来,这样可以消除庞大的条件分支语句,因为大的分支判断使得它们难以修改和扩展。
缺点:添加了许多状态类,使程序变得复杂。