重点概念
1. 方法内容如果过长其实就有可能出了问题。
2. 当一个对象的内在状态改变时通过调用状态类(一个类)中的方法,同事传递自己(this),状态的判断及执行全部移到了这个状态类当中。
3. 状态模式主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑简化。
4. 状态模式的好处是将与特定状态相关的行为局部化,并且将不同的状态的行为分割开来
5. 状态模式是在判断类(Context)中拥有一个抽象状态成员,初始化一个具体的状态对象,在判断类中的状态改变方法中,调用状态对象的公共方法,在这个方法中会要求传入包含状态对象的判断对象this做参数,然后在具体的状态类中去改变this的状态对象,也就是判断类中的状态对象。
6.将特定的状态相关的行为都放入一个对象(ConcreteState )中,由于所有与状态相关的代码都存在于某个ConcreteState 中,所以通过定义新的子类可以很容易地添加新的状态和转换。
7.状态模式的作用就是用于消除庞大的条件分支语句。
8.状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。
示例程序
using System; using System.Collections.Generic; using System.Text; namespace 状态模式 { 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(); } } }
上班状态的状态模式版本
类图
代码
using System; using System.Collections.Generic; using System.Text; namespace 状态模式 { 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); } } }
冯瑞涛