状态模式(State):当一个内在对象的状态改变时允许改变其行为,这个对象看起来像是改变了其类。状态模式主要解决的是当控制一个对象状态改变的条件表达式过于复杂的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑化。
好处是将与特定状态的行为局部化,并且将不同状态的行为分割开来。将特定的状态相关行为都放入一个对象中,由于所有与状态相关的代码都存在某个ConcreteState当中,所以通过定义新的子类可以很容易地增加新的状态和转换,消除了庞大的条件分支语句,状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。
- using System;
- /**
- * 状态模式(State):
- * 当一个内在对象的状态改变时允许改变其行为,这个对象看起来像是改变了其类。状态模式主要解决的是当控制一个对象状态改变的条件表达式过于复杂的情况。把状态的判断逻辑转移到表示不同状态的一系列类当中,可以把复杂的判断逻辑化。
- * 好处是将与特定状态的行为局部化,并且将不同状态的行为分割开来。将特定的状态相关行为都放入一个对象中,由于所有与状态相关的代码都存在某个ConcreteState当中,所以通过定义新的子类可以很容易地增加新的状态和转换,消除了庞大的条件分支语句,状态模式通过把各种状态转移逻辑分布到State的子类之间,来减少相互间的依赖。
- 当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,就可以考虑使用状态模式了。
- */
- namespace StuDesignMode.State
- {
- #region 状态模式原始代码
- //interface IState
- //{
- // void Handle(Context context);
- //}
- //class ConcreteStateA : IState
- //{
- // public void Handle(Context context)
- // {
- // //设置A的下一状态是B
- // context.State = new ConcreteStateB();
- // }
- //}
- //class ConcreteStateB : IState
- //{
- // public void Handle(Context context)
- // {
- // //设置B的下一状态是A
- // context.State = new ConcreteStateA();
- // }
- //}
- //class Context
- //{
- // private IState _state;
- // public IState State
- // {
- // get { return this._state; }
- // set { this._state = value; Console.WriteLine("当前状态:",this._state.GetType().Name); }
- // }
- // public void Request()
- // {
- // this.State.Handle(this);
- // }
- //}
- #endregion
- #region 模式示例
- public interface IState
- {
- void WriteProgram(Work work);
- }
- /// <summary>
- /// 上午状态
- /// </summary>
- public class ForenoonState : IState
- {
- public void WriteProgram(Work work)
- {
- if (work.Hour < 12)
- {
- Console.WriteLine("当前时间:{0}点 上午工作,精神百倍!", work.Hour);
- }
- else
- {
- work.CurrentState = new NoonState();
- work.WriteProgram();
- }
- }
- }
- /// <summary>
- /// 中午状态
- /// </summary>
- public class NoonState : IState
- {
- public void WriteProgram(Work work)
- {
- if (work.Hour < 13)
- {
- Console.WriteLine("当前时间:{0}点 饿了,午饭;困了,午休。", work.Hour);
- }
- else
- {
- work.CurrentState = new AfternoonState();
- work.WriteProgram();
- }
- }
- }
- /// <summary>
- /// 下午工作状态
- /// </summary>
- public class AfternoonState : IState
- {
- public void WriteProgram(Work work)
- {
- if (work.Hour < 17)
- {
- Console.WriteLine("当前时间:{0}点 下午状态还不错,继续努力!", work.Hour);
- }
- else
- {
- //工作完成,下班回家
- if (work.TaskFinished)
- {
- work.CurrentState = new RestState();
- work.WriteProgram();
- }
- else//加班
- {
- work.CurrentState = new EveningState();
- work.WriteProgram();
- }
- }
- }
- }
- /// <summary>
- /// 晚间工作状态
- /// </summary>
- public class EveningState : IState
- {
- public void WriteProgram(Work work)
- {
- if (work.TaskFinished)
- {
- work.CurrentState = new RestState();
- work.WriteProgram();
- }
- else
- {
- if (work.Hour < 21)
- {
- Console.WriteLine("当前时间:{0}点 加班哦,疲惫之急!", work.Hour);
- }
- else
- {
- work.CurrentState = new SleepingState();
- work.WriteProgram();
- }
- }
- }
- }
- /// <summary>
- /// 下班了
- /// </summary>
- public class RestState : IState
- {
- public void WriteProgram(Work work)
- {
- Console.WriteLine("当前时间:{0}点 工作完成了,下班,回家!",work.Hour);
- }
- }
- /// <summary>
- /// 睡眠时间
- /// </summary>
- public class SleepingState : IState
- {
- public void WriteProgram(Work work)
- {
- Console.WriteLine("当前时间:{0}点 不行了,困死了,要睡觉!",work.Hour);
- }
- }
- public class Work
- {
- /// <summary>
- /// 工作状态
- /// </summary>
- public IState CurrentState { get; set; }
- /// <summary>
- /// 当前时间
- /// </summary>
- public double Hour { get; set; }
- /// <summary>
- /// 工作是是否完成
- /// </summary>
- public bool TaskFinished { get; set; }
- public Work()
- {
- //默认为上午工作状态
- this.CurrentState = new ForenoonState();
- }
- public void WriteProgram()
- {
- this.CurrentState.WriteProgram(this);
- }
- }
- //测试
- class ClientTest
- {
- static void Main(string[] args)
- {
- Work worker = new Work();
- worker.Hour = 9;
- worker.WriteProgram();
- worker.Hour = 11;
- worker.WriteProgram();
- worker.Hour = 12.50;
- worker.WriteProgram();
- worker.Hour = 14;
- worker.WriteProgram();
- worker.Hour = 16;
- worker.TaskFinished = true;
- worker.WriteProgram();
- worker.Hour = 18;
- worker.WriteProgram();
- worker.Hour = 20;
- worker.WriteProgram();
- worker.Hour = 22;
- worker.WriteProgram();
- Console.WriteLine();
- }
- }
- #endregion
- }