CSharp: State Pattern in donet core 3
/// <summary> /// 状态模式 State Pattern /// geovindu, Geovin Du edit /// </summary> interface IPossibleStates { //Users can press any of these buttons-On, Off or Mute /// <summary> /// /// </summary> /// <param name="context"></param> void PressOnButton(TV context); /// <summary> /// /// </summary> /// <param name="context"></param> void PressOffButton(TV context); /// <summary> /// /// </summary> /// <param name="context"></param> void PressMuteButton(TV context); } //Subclasses does not contain any local state. //Only one unique instance of IPossibleStates is required. /// <summary> /// Off state behavior /// 关状态行为 /// </summary> class Off : IPossibleStates { /// <summary> /// 关 /// </summary> public Off() { Console.WriteLine("---电视现在是关的 TV is Off now.---\n"); } /// <summary> /// TV is Off now, user is pressing On button /// 现在电视是关闭的,用户正在按开按钮 /// 下一个开按钮 /// </summary> /// <param name="context"></param> public void PressOnButton(TV context) { Console.WriteLine("TV was Off电视是关的.Going from Off to On state.是从关状态至开的状诚"); context.CurrentState = new On(); } /// <summary> /// TV is Off already, user is pressing Off button again /// 现在电视是关闭的,用户正在按打开按钮电视是关闭的,用户正在按关闭按钮再次 /// </summary> /// <param name="context"></param> public void PressOffButton(TV context) { Console.WriteLine("TV was already in Off state现在电视是关闭状态.So, ignoring this opeation.所以,忽略这个操作"); } /// <summary> /// TV is Off now, user is pressing Mute button /// 电视关闭,用户按静音键 /// </summary> /// <param name="context"></param> public void PressMuteButton(TV context) { Console.WriteLine("TV was already off.电视已经关闭 So, ignoring this operation.所以,可以忽略这个操作"); } } /// <summary> /// On state behavior /// 开状态行为 /// </summary> class On : IPossibleStates { /// <summary> /// /// </summary> public On() { Console.WriteLine("---电视现在是开的。TV is On now.---\n"); } //Users can press any of these buttons at this state-On, Off or Mute //TV is On already, user is pressing On button again public void PressOnButton(TV context) { Console.WriteLine("TV is already in On state.电视已经是开的状诚。Ignoring repeated on button press operation.忽略重复按下按钮操作"); } //TV is On now, user is pressing Off button public void PressOffButton(TV context) { Console.WriteLine("TV was on.现在电视是开的,So,switching off the TV.所以,可以正当关掉电视"); context.CurrentState = new Off(); } //TV is On now, user is pressing Mute button public void PressMuteButton(TV context) { Console.WriteLine("TV was on.现在电视是开状态。So,moving to silent mode.所以,切换到静音模式"); context.CurrentState = new Mute(); } } /// <summary> /// Mute state behavior /// 静音状态行为 /// </summary> class Mute : IPossibleStates { public Mute() { Console.WriteLine("---电视现在是静音模式 TV is in Mute mode now.---\n"); } //Users can press any of these buttons at this state-On, Off or Mute //TV is in mute, user is pressing On button public void PressOnButton(TV context) { Console.WriteLine("TV was in mute mode.现在是静音模式,So, moving to normal state.那么,可以转换为正常状态"); context.CurrentState = new On(); } //TV is in mute, user is pressing Off button public void PressOffButton(TV context) { Console.WriteLine("TV was in mute mode.现在是静音模式 So, switching off the TV.那么,现在可以关闭电视。"); context.CurrentState = new Off(); } //TV is in mute already, user is pressing mute button again public void PressMuteButton(TV context) { Console.WriteLine(" TV is already in Mute mode,电视已经处于静音状态 so, ignoring this operation.那么,可以忽略这个操作"); } } /// <summary> /// TV is the context class /// 电视对象 /// </summary> class TV { /// <summary> /// /// </summary> private IPossibleStates currentState; /// <summary> /// /// </summary> public IPossibleStates CurrentState { get { return currentState; } /* * Usually this value will be set by the class that implements the interface "IPossibleStates" */ set { currentState = value; } } /// <summary> /// /// </summary> public TV() { //Starting with Off state this.currentState = new Off(); } /// <summary> /// /// </summary> public void ExecuteOffButton() { Console.WriteLine("你按下“关闭”按钮."); //Delegating the state behavior currentState.PressOffButton(this); } /// <summary> /// /// </summary> public void ExecuteOnButton() { Console.WriteLine("你按下“打开”按钮."); //Delegating the state behavior currentState.PressOnButton(this); } /// <summary> /// /// </summary> public void ExecuteMuteButton() { Console.WriteLine("您按了静音键."); //Delegating the state behavior currentState.PressMuteButton(this); } }
/// <summary> /// 状态模式 State Pattern /// geovindu, Geovin Du edit /// </summary> public class DuProgram { public enum Trigger { On, Off } } /// <summary> /// /// </summary> public enum State { OffHook, CallDialed, Ringing, OnHold, OnHook }
/// <summary> /// 状态模式 State Pattern /// geovindu, Geovin Du edit /// </summary> public enum Chest { Open, Closed, Locked } /// <summary> /// /// </summary> public enum Action { Open, Close } /// <summary> /// /// </summary> public class SwitchExpressions { /// <summary> /// /// </summary> /// <param name="chest"></param> /// <param name="action"></param> /// <param name="haveKey"></param> /// <returns></returns> public static Chest Manipulate(Chest chest, Action action, bool haveKey) => (chest, action, haveKey) switch { (Chest.Closed, Action.Open, _) => Chest.Open, (Chest.Locked, Action.Open, true) => Chest.Open, (Chest.Open, Action.Close, true) => Chest.Locked, (Chest.Open, Action.Close, false) => Chest.Closed, _ => chest }; /// <summary> /// /// </summary> /// <param name="chest"></param> /// <param name="action"></param> /// <param name="haveKey"></param> /// <returns></returns> public static Chest Manipulate2(Chest chest, Action action, bool haveKey) { switch (chest, action, haveKey) { case (Chest.Closed, Action.Open, _): return Chest.Open; case (Chest.Locked, Action.Open, true): return Chest.Open; case (Chest.Open, Action.Close, true): return Chest.Locked; case (Chest.Open, Action.Close, false): return Chest.Closed; default: Console.WriteLine("Chest unchanged"); return chest; } } }
调用:
//状态模式 Console.WriteLine("***状态模式 State Pattern Demo***\n"); //TV is initialized with Off state. TV tv = new TV(); Console.WriteLine("用户按以下顺序按按钮:"); Console.WriteLine("Off->Mute->On->On->Mute->Mute->Off\n"); //TV is already in Off state tv.ExecuteOffButton(); //TV is already in Off state, still pressing the Mute button tv.ExecuteMuteButton(); //Making the TV on tv.ExecuteOnButton(); //TV is already in On state, pressing On button again tv.ExecuteOnButton(); //Putting the TV in Mute mode tv.ExecuteMuteButton(); //TV is already in Mute, pressing Mute button again tv.ExecuteMuteButton(); //Making the TV off tv.ExecuteOffButton(); Console.WriteLine(); // false = off, true = on var light = new StateMachine<bool, DuProgram.Trigger>(false);////引用了 https://github.com/dotnet-state-machine/stateless light.Configure(false) // if the light is off... .Permit(DuProgram.Trigger.On, true) // we can turn it on .OnEntry(transition => { if (transition.IsReentry) Console.WriteLine("Light is already off!"); else Console.WriteLine("Switching light off"); }) .PermitReentry(DuProgram.Trigger.Off); // .Ignore(Trigger.Off) // but if it's already off we do nothing // same for when the light is on light.Configure(true) .Permit(DuProgram.Trigger.Off, false) .OnEntry(() => Console.WriteLine("Turning light on")) .Ignore(DuProgram.Trigger.On); light.Fire(DuProgram.Trigger.On); // Turning light on light.Fire(DuProgram.Trigger.Off); // Turning light off light.Fire(DuProgram.Trigger.Off); // Light is already off! Console.WriteLine(); // Chest chest = Chest.Locked; Console.WriteLine($"Chest is {chest}"); // unlock with key chest = SwitchExpressions.Manipulate(chest, Action.Open, true); Console.WriteLine($"Chest is now {chest}"); // close it! chest = SwitchExpressions.Manipulate(chest, Action.Close, false); Console.WriteLine($"Chest is now {chest}"); // close it again! chest = SwitchExpressions.Manipulate(chest, Action.Close, false); Console.WriteLine($"Chest is now {chest}");
输出:
***状态模式 State Pattern Demo*** ---电视现在是关的 TV is Off now.--- 用户按以下顺序按按钮: Off->Mute->On->On->Mute->Mute->Off 你按下“关闭”按钮. TV was already in Off state现在电视是关闭状态.So, ignoring this opeation.所以,忽略这个操作 您按了静音键. TV was already off.电视已经关闭 So, ignoring this operation.所以,可以忽略这个操作 你按下“打开”按钮. TV was Off电视是关的.Going from Off to On state.是从关状态至开的状诚 ---电视现在是开的。TV is On now.--- 你按下“打开”按钮. TV is already in On state.电视已经是开的状诚。Ignoring repeated on button press operation.忽略重复按下按钮操作 您按了静音键. TV was on.现在电视是开状态。So,moving to silent mode.所以,切换到静音模式 ---电视现在是静音模式 TV is in Mute mode now.--- 您按了静音键. TV is already in Mute mode,电视已经处于静音状态 so, ignoring this operation.那么,可以忽略这个操作 你按下“关闭”按钮. TV was in mute mode.现在是静音模式 So, switching off the TV.那么,现在可以关闭电视。 ---电视现在是关的 TV is Off now.--- Turning light on Switching light off Light is already off! Chest is Locked Chest is now Open Chest is now Closed Chest is now Closed
哲学管理(学)人生, 文学艺术生活, 自动(计算机学)物理(学)工作, 生物(学)化学逆境, 历史(学)测绘(学)时间, 经济(学)数学金钱(理财), 心理(学)医学情绪, 诗词美容情感, 美学建筑(学)家园, 解构建构(分析)整合学习, 智商情商(IQ、EQ)运筹(学)生存.---Geovin Du(涂聚文)