设计模式-行为型-状态模式
状态模式(state):
在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理。最直接的解决方案是将这些所有可能发生的情况全都考虑到,然后使用if else语句来做状态判断来进行不同情况的处理。但对复杂状态的判断就显得"力不从心了",随着增加新的状态或者修改一个状体if else(或switch case)语句的增多或者修改)可能会引起很大的修改,违反ocp原则。状态模式就是在当控制一个对象状态转换的条件表达式过于复杂时,把相关"判断逻辑"提取出来,放到一系列的状态类当中,这样可以把原来复杂的逻辑判断简单化。
状态模式的角色:
1)环境类(context):也称为上下文,它定义了客户感兴趣的接口,维护一个当前状态,并将与状态相关的操作委托给当前状态对象来处理。
2)抽象状态类(abstractstate):定义一个接口以封装与context的一个特定状态相关的行为。
3)具体状态类(concretestate):实现抽象状态所对应的行为。
状态模式的代码实现:
1 internal class program 2 { 3 private static void main(string[] args) 4 { 5 // setup context in a state 6 context c = new context(new concretestatea()); 7 8 // issue requests, which toggles state 9 c.request(); 10 c.request(); 11 } 12 } 13 14 public abstract class abstractstate 15 { 16 public abstract void handler(context context); 17 } 18 19 public class context 20 { 21 private abstractstate state; 22 23 public context(abstractstate state) 24 { 25 this.state = state; 26 } 27 28 public abstractstate state 29 { 30 get 31 { 32 return state; 33 } 34 set 35 { 36 state = value; 37 console.writeline("state: " + state.gettype().name); 38 } 39 } 40 41 public void request() 42 { 43 state.handler(this); 44 } 45 } 46 47 public class concretestatea : abstractstate 48 { 49 public override void handler(context context) 50 { 51 context.state = new concretestateb(); 52 } 53 } 54 55 public class concretestateb : abstractstate 56 { 57 public override void handler(context context) 58 { 59 context.state = new concretestatec(); 60 } 61 } 62 63 public class concretestatec : abstractstate 64 { 65 public override void handler(context context) 66 { 67 context.state = new concretestatea(); 68 } 69 }
实例:(以电灯开关为例)
1 internal class program 2 { 3 private static void main(string[] args) 4 { 5 light light = new light(new lightoff()); 6 light.pressswich(); 7 light.pressswich(); 8 } 9 } 10 11 /// <summary> 12 /// 抽象电灯状态类 13 /// </summary> 14 public abstract class lightstate 15 { 16 public abstract void pressswich(light light); 17 } 18 19 public class light 20 { 21 private lightstate state; 22 23 public light(lightstate state) 24 { 25 this.state = state; 26 } 27 28 public lightstate state 29 { 30 get { return state; } 31 set { state = value; } 32 } 33 34 public void pressswich() 35 { 36 state.pressswich(this); 37 } 38 } 39 40 /// <summary> 41 /// 电灯打开状态 42 /// </summary> 43 public class lighton : lightstate 44 { 45 public override void pressswich(light light) 46 { 47 console.writeline("turn off the light."); 48 light.state = new lightoff(); 49 } 50 } 51 52 /// <summary> 53 /// 电灯关闭状态 54 /// </summary> 55 public class lightoff : lightstate 56 { 57 public override void pressswich(light light) 58 { 59 console.writeline("turn on the light."); 60 light.state = new lighton(); 61 } 62 }
状态模式的优缺点:
优点:
1)状态模式将与特定状态相关的行为局部化到一个状态中,并且将不同状态的行为分割开来,满足“”。
2)减少对象间的相互依赖。将不同的状态引入独立的对象中会使得状态转换变得更加明确,且减少对象间的相互依赖。
3)有利于程序的扩展。通过定义新的子类很容易地增加新的状态和转换。
缺点:
1)状态模式的使用必然会增加系统的类与对象的个数。
2)状态模式的结构与实现都较为复杂,如果使用不当会导致程序结构和代码的混乱。
状态模式的应用场景:
1)当一个对象的行为取决于它的状态,并且它必须在运行时根据状态改变它的行为。
2)一个操作中含有庞大的分支结构,并且这些分支决定于对象的状态。
状态模式与的区别:
从uml图上我们会发现这两种设计模式几乎一摸一样,都是利用多态把一些操作分配到一组相关的简单的类中。然而在显示世界中,策略模式和状态模式是两种完全不同的思想。对状态进行建模时,状态迁移是一个核心问题;但策略模式与迁移毫无关系,策略模式允许一个客户选择或提供一种策略。
状态模式与的区别:
职责链模式和状态模式都可以解决if分支过多的问题,从定义来看,状态模式是一个对象内在状态发生改变(一个对象,相对稳定,处理完一个对象下一个对象一般已确定),而职责链模式是多个对象之间的改变(多个对象之间的话,就会出现某个对象不存在的问题,且该模式由客户端指定,不稳定),这也说明了这两个模式处理的情况不同。
参考:
上一篇: 腿抽筋怎么办?快速缓解的方法,不必求人