状态模式旨在容许对象在其内部状态改变时改变其自身行为。git
咱们以烤牛排为例,生熟程度分为:github
简单来讲就是从生到熟的几个档次。ide
抽象的状态类:ui
/// <summary> /// The State abstract class /// </summary> abstract class Doneness { protected Steak steak; protected double currentTemp; protected double lowerTemp; protected double upperTemp; protected bool canEat; public Steak Steak { get { return steak; } set { steak = value; } } public double CurrentTemp { get { return currentTemp; } set { currentTemp = value; } } public abstract void AddTemp(double temp); public abstract void RemoveTemp(double temp); public abstract void DonenessCheck(); }
具体的状态类:this
/// <summary> /// A Concrete State class. /// </summary> class Uncooked : Doneness { public Uncooked(Doneness state) { currentTemp = state.CurrentTemp; steak = state.Steak; Initialize(); } private void Initialize() { lowerTemp = 0; upperTemp = 130; canEat = false; } public override void AddTemp(double amount) { currentTemp += amount; DonenessCheck(); } public override void RemoveTemp(double amount) { currentTemp -= amount; DonenessCheck(); } public override void DonenessCheck() { if (currentTemp > upperTemp) { steak.State = new Rare(this); } } } /// <summary> /// A 'ConcreteState' class. /// </summary> class Rare : Doneness { public Rare(Doneness state) : this(state.CurrentTemp, state.Steak) { } public Rare(double currentTemp, Steak steak) { this.currentTemp = currentTemp; this.steak = steak; canEat = true; //We can now eat the steak Initialize(); } private void Initialize() { lowerTemp = 130; upperTemp = 139.999999999999; canEat = true; } public override void AddTemp(double amount) { currentTemp += amount; DonenessCheck(); } public override void RemoveTemp(double amount) { currentTemp -= amount; DonenessCheck(); } public override void DonenessCheck() { if (currentTemp < lowerTemp) { steak.State = new Uncooked(this); } else if (currentTemp > upperTemp) { steak.State = new MediumRare(this); } } } /// <summary> /// A Concrete State class /// </summary> class MediumRare : Doneness { public MediumRare(Doneness state) : this(state.CurrentTemp, state.Steak) { } public MediumRare(double currentTemp, Steak steak) { this.currentTemp = currentTemp; this.steak = steak; canEat = true; Initialize(); } private void Initialize() { lowerTemp = 140; upperTemp = 154.9999999999; } public override void AddTemp(double amount) { currentTemp += amount; DonenessCheck(); } public override void RemoveTemp(double amount) { currentTemp -= amount; DonenessCheck(); } public override void DonenessCheck() { if (currentTemp < 0.0) { steak.State = new Uncooked(this); } else if (currentTemp < lowerTemp) { steak.State = new Rare(this); } else if (currentTemp > upperTemp) { steak.State = new Medium(this); } } } /// <summary> /// A Concrete State class /// </summary> class Medium : Doneness { public Medium(Doneness state) : this(state.CurrentTemp, state.Steak) { } public Medium(double currentTemp, Steak steak) { this.currentTemp = currentTemp; this.steak = steak; canEat = true; Initialize(); } private void Initialize() { lowerTemp = 155; upperTemp = 169.9999999999; } public override void AddTemp(double amount) { currentTemp += amount; DonenessCheck(); } public override void RemoveTemp(double amount) { currentTemp -= amount; DonenessCheck(); } public override void DonenessCheck() { if (currentTemp < 130) { steak.State = new Uncooked(this); } else if (currentTemp < lowerTemp) { steak.State = new MediumRare(this); } else if (currentTemp > upperTemp) { steak.State = new WellDone(this); } } } /// <summary> /// A Concrete State class /// </summary> class WellDone : Doneness //aka Ruined { public WellDone(Doneness state) : this(state.CurrentTemp, state.Steak) { } public WellDone(double currentTemp, Steak steak) { this.currentTemp = currentTemp; this.steak = steak; canEat = true; Initialize(); } private void Initialize() { lowerTemp = 170; upperTemp = 230; } public override void AddTemp(double amount) { currentTemp += amount; DonenessCheck(); } public override void RemoveTemp(double amount) { currentTemp -= amount; DonenessCheck(); } public override void DonenessCheck() { if (currentTemp < 0) { steak.State = new Uncooked(this); } else if (currentTemp < lowerTemp) { steak.State = new Medium(this); } } }
上下文类-牛排:spa
/// <summary> /// The Context class /// </summary> class Steak { private Doneness _state; private string _beefCut; public Steak(string beefCut) { _cook = beefCut; _state = new Rare(0.0, this); } public double CurrentTemp { get { return _state.CurrentTemp; } } public Doneness State { get { return _state; } set { _state = value; } } public void AddTemp(double amount) { _state.AddTemp(amount); Console.WriteLine("Increased temperature by {0} degrees.", amount); Console.WriteLine(" Current temp is {0}", CurrentTemp); Console.WriteLine(" Status is {0}", State.GetType().Name); Console.WriteLine(""); } public void RemoveTemp(double amount) { _state.RemoveTemp(amount); Console.WriteLine("Decreased temperature by {0} degrees.", amount); Console.WriteLine(" Current temp is {0}", CurrentTemp); Console.WriteLine(" Status is {0}", State.GetType().Name); Console.WriteLine(""); } }
客户端调用:.net
static void Main(string[] args) { //Let's cook a steak! Steak account = new Steak("T-Bone"); // Apply temperature changes account.AddTemp(120); account.AddTemp(15); account.AddTemp(15); account.RemoveTemp(10); //Yes I know cooking doesn't work this way, bear with me. account.RemoveTemp(15); account.AddTemp(20); account.AddTemp(20); account.AddTemp(20); Console.ReadKey(); }
状态模式容许对象的行为随着其内部状态的改变而改变,而且它经过使对象的状态与对象自己分开来完成这一任务。
所以,状态能够为对象实现它们本身的行为,而且对象能够对其内部状态改变做出“反应”。code
https://github.com/exceptionnotfound/DesignPatterns/tree/master/State对象
https://www.exceptionnotfound.net/state-the-daily-design-pattern/get