欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

设计模式-行为型-状态模式

程序员文章站 2023-11-13 13:54:28
状态模式(State): 在软件开发过程中,应用程序可能会根据不同的情况作出不同的处理。最直接的解决方案是将这些所有可能发生的情况全都考虑到,然后使用if else语句来做状态判断来进行不同情况的处理。但对复杂状态的判断就显得"力不从心了",随着增加新的状态或者修改一个状体if else(或swit ......

状态模式(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分支过多的问题,从定义来看,状态模式是一个对象内在状态发生改变(一个对象,相对稳定,处理完一个对象下一个对象一般已确定),而职责链模式是多个对象之间的改变(多个对象之间的话,就会出现某个对象不存在的问题,且该模式由客户端指定,不稳定),这也说明了这两个模式处理的情况不同。

参考: