一,概述
狀態模式:允許對象在內部狀態改變時改變它的行為,對象看起來好像修改了它的類。
狀態模式主要解決的是當控制一個對象狀態的條件運算式過於複雜時的情況。把狀態的判斷邏輯轉移到表示不同狀態的一系列類中,可以把複雜的判斷邏輯簡化。
意圖:允許一個對象在其內部狀態改變時改變它的行為
適用情境:
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(); } }