一、概念:
当一个对象的内在状态改变时,允许改变其行为,这个对象看起来像是改变了其类。【DP】
二、作用:
状态模式的主要解决的是当控制一个对象状态转换的条件表达式过于复杂时的情况。
吧状态的判断逻辑转移到表示不同状态的一系列当中,可以把复杂的判断逻辑简化。
当然如果这个状态的判断很简单,那么就没必要用“状态模式”了,千万注意不要为了设计模式而去用设计模式。
三、通俗的概念理解:
就是为了消除庞大的条件分支语句。当一个对象的行为取决于他的状态,并且他必须在运行时刻根据状态改变他的行为时,就可以考虑使用状态模式了。
四、状态模式类图;
五、对概念的理解和针对类图进行代码的翻译;
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace State 8 { 9 //State类,抽象状态类,定义一个接口一封装与Context的一个特定状态相关的行为10 public abstract class State11 {12 public abstract void Handle(Context context);13 }14 15 //ConcreteState类,具体状态类,每一个子类实现一个与Context的一个状态相关的行为16 public class ConcreteStateA : State17 {18 public override void Handle(Context context)19 {20 context.State = new ConcreteStateB(); //设置ConcreStateA的下一状态是ConcreStateB21 }22 }23 24 public class ConcreteStateB : State25 {26 public override void Handle(Context context)27 {28 context.State = new ConcreteStateA(); //设置ConcreStateB的下一状态是ConcreStateA29 }30 }31 32 //Context类,维护一个ConcreteState子类的实例,这个实例定义当前的状态33 public class Context34 {35 private State state;36 public State State37 {38 get { return state; }39 set40 {41 state = value;42 Console.WriteLine("当前状态:" + state.GetType().Name);43 }44 }45 46 public Context(State state) //定义Context的初始状态47 {48 this.state = state;49 }50 51 public void Request()52 {53 state.Handle(this); //对请求做处理,并设置下一状态54 }55 56 }57 58 class Program59 {60 //客户端代码;61 static void Main(string[] args)62 {63 Context context = new Context(new ConcreteStateA()); //设置Context的初始状态为ConcreStateA64 65 context.Request();66 context.Request();67 context.Request();68 context.Request();69 Console.ReadKey();70 71 }72 }73 }
结果显示;
六、接下啦就是对概念进行实例的操作了,概念记得再熟,也不如实战一把,
那我这里就是以程序员的加班来进行案例的解释了,对一天的工作时间与下班来进行一个状态的切换。
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace Test_02 8 { 9 10 //抽象的状态 11 public abstract class State 12 { 13 public abstract void WriteProgram(Work work); 14 } 15 16 //上午的工作状态 17 public class ForenoonState : State 18 { 19 public override void WriteProgram(Work work) 20 { 21 if (work.Hour < 12) 22 { 23 Console.WriteLine("当前时间:" + work.Hour + "点,上午工作,精神还行"); 24 } 25 else //否则,超过12点进行状态的切换 26 { 27 work.SetState(new NoonState()); 28 work.WriteProgram(); 29 } 30 } 31 } 32 33 //中午的工作状态 34 public class NoonState : State 35 { 36 public override void WriteProgram(Work work) 37 { 38 if (work.Hour < 13) 39 { 40 Console.WriteLine("当前时间:" + work.Hour + "点,中午,饿了,犯困"); 41 } 42 else //转到下午的工作状态 43 { 44 work.SetState(new AfternoonState()); 45 work.WriteProgram(); 46 } 47 48 49 } 50 } 51 52 public class AfternoonState : State 53 { 54 public override void WriteProgram(Work work) 55 { 56 if (work.Hour < 17) 57 { 58 Console.WriteLine("当前时间:" + work.Hour + "点,下午状态还不错,继续努力"); 59 } 60 else//否则,转为傍晚的工作状态 61 { 62 work.SetState(new EveningState()); 63 work.WriteProgram(); 64 } 65 66 } 67 } 68 //晚间工作状态 69 public class EveningState : State 70 { 71 public override void WriteProgram(Work work) 72 { 73 if (work.Finish == true) //当工作完成了,则转入下班的装态 74 { 75 work.SetState(new RestState()); 76 work.WriteProgram(); 77 } 78 else 79 { 80 if (work.Hour < 21) 81 { 82 Console.WriteLine("当前时间:" + work.Hour + "点,加班哦,疲累至极"); 83 } 84 else //当时间超过21点则转入睡觉的状态 85 { 86 work.SetState(new SleepState()); 87 work.WriteProgram(); 88 } 89 } 90 } 91 } 92 //睡眠状态 93 public class SleepState : State 94 { 95 public override void WriteProgram(Work work) 96 { 97 Console.WriteLine("当前时间:" + work.Hour + "点,已经撑不住了,睡着了"); 98 } 99 }100 101 //下班休息状态102 public class RestState : State103 {104 public override void WriteProgram(Work work)105 {106 Console.WriteLine("当前时间:" + work.Hour + "点,下吧回家休息了");107 }108 }109 110 //工作类111 public class Work112 {113 private State current;114 public Work()115 {116 current = new ForenoonState();//工作的初始状态为上午工作状太,9点开始工作117 }118 private double hour; //属性,状态切换的依据119 120 public double Hour121 {122 get { return hour; }123 set124 {125 hour = value;126 }127 }128 129 private bool finish = false; //任务完成标志,是否能下班的标志130 131 public bool Finish132 {133 get { return finish; }134 set { finish = value; }135 }136 137 public void SetState(State state)138 {139 current = state;140 }141 142 public void WriteProgram()143 {144 current.WriteProgram(this);145 }146 147 }148 class Program149 {150 static void Main(string[] args)151 {152 Work work = new Work();153 work.Hour = 19;154 work.WriteProgram();155 Console.ReadKey();156 }157 }158 }
七、总结:
当一个对象的行为取决于他的状态,并且他必须在运行时刻根据状态改变他的行为时,就可以考虑使用状态模式了,
例如可以在角色的AI切换的时候使用,在游戏界面的登录界面以及其他界面的切换中使用,
八:扩充:
在写代码的时候,一定要避免在一个类中的方法过于太长了的情况发生,看起来也是不太爽的是吧!
2017-12-14 00:27:06