赞
踩
某个行为需要根据不同条件做出反应,将这些条件划分到状态类
对象的行为依赖于它的状态(属性),并且可以根据它的状态改变而改变它的相关行为。代码中包含大量与对象状态有关的条件语句。当一个对象状态的条件判断表达式过于复杂,可以将状态的判断逻辑转移到一系列状态类,可以把复杂的判断逻辑简化。
UML图
State: 状态抽象类,提供一个状态转换的接口
StateA、StateB、StateC:具体状态类,实现状态之间的过渡顺序
Context:环境类,提供状态切换的环境条件,条件变换时,状态也对应变换
一个状态的改变是根据多条件判断的结果,这个状态是运行时跟随条件变化的。比如今天上班的状态根据时间改变,上午精神,下午萎靡,晚上想睡觉。比如我今天出门是穿什么衣服是根据天气决定的,大晴天短袖,雨天雨衣,冬天羽绒服,雾霾戴口罩。总归一个对象的状态改变是根据不同条件做出的反应,就可以考虑用状态模式了。
优点
减弱了条件之间的逻辑复杂度
代码简洁好维护,转换逻辑与状态对象合为一体
缺点
开闭原则不好增加不同状态需要增加状态类,再修改已有的状态类进行过渡
结构与实现比较复杂,使用不当会有混乱的感觉
增加了类的个数
上班状态根据时间改变而变化, 小菜的上班状态大致分为五个状态,①上午②中午③下午④晚上⑤很晚,状态就是根据时间线过渡的,环境类持有一个状态变量,表示当前状态,一个写程序的方法,方法调用的是当前状态的执行方法。状态一旦改变,对应的执行方法具体实现也不一样。
using System; namespace StateMode { class Program { static void Main(string[] args) { Naruto naruto = new Naruto(); naruto.Chakela = 4000; naruto.Requst(); naruto.Chakela = 300000; naruto.Requst(); naruto.Chakela = 40000000; naruto.Requst(); naruto.SixFairyPower = true; naruto.Chakela = 40000000; naruto.Requst(); naruto.Chakela = 400; naruto.Requst(); Console.ReadKey(); } } public class Naruto { State state;//普通 仙人 尾兽 六道 1000 50000 2000000 bool sixFairyPower = false;//六道仙人的力量 int chakela;//查克拉 public State NarutoState { get { return state; } set { state = value; } } public bool SixFairyPower { get { return sixFairyPower; } set { sixFairyPower = value; } } public int Chakela { get => chakela; set => chakela = value; } public void Requst() { state = new NormalState(); state.Handler(this); } } public interface State { void Handler(Naruto naruto); } public class NormalState : State { public void Handler(Naruto naruto) { if (naruto.Chakela < 1000) { Console.Write("当前查克拉{0},六道阳之力解锁状态:{1};", naruto.Chakela, naruto.SixFairyPower); Console.WriteLine("螺旋丸"); } else { naruto.NarutoState = new ImmortalState(); naruto.NarutoState.Handler(naruto); } } } public class ImmortalState : State { public void Handler(Naruto naruto) { if (naruto.Chakela < 50000) { Console.Write("当前查克拉{0},六道阳之力解锁状态:{1};", naruto.Chakela, naruto.SixFairyPower); Console.WriteLine("仙法.螺旋丸手里剑"); } else { naruto.NarutoState = new NineTialFoxState(); naruto.NarutoState.Handler(naruto); } } } public class NineTialFoxState : State { public void Handler(Naruto naruto) { if (naruto.SixFairyPower && naruto.Chakela >= 2000000) { naruto.NarutoState = new SixRealmsState(); naruto.NarutoState.Handler(naruto); } else { Console.Write("当前查克拉{0},六道阳之力解锁状态:{1};", naruto.Chakela, naruto.SixFairyPower); Console.WriteLine("尾兽炮"); } } } public class SixRealmsState : State { public void Handler(Naruto naruto) { Console.Write("当前查克拉{0},六道阳之力解锁状态:{1};", naruto.Chakela, naruto.SixFairyPower); Console.WriteLine("求道玉"); } } }
运行结果
PS:目前来看状态模式并未给自己减轻多少负担,反倒增添了不少工作量,假如我不用状态模式,直接在一个方法里面做条件判断,反倒轻松一些。或许是在单一状态下的条件不够复杂,状态模式的优势显示不出来。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。