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

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

参考:https://www.runoob.com/w3cnote/state-vs-strategy.html

  https://blog.csdn.net/hguisu/article/details/7557252

(0)

相关推荐

  • 简说设计模式——状态模式

    一.什么是状态模式 状态这个词汇我们并不陌生,在日常生活中,不同时间就有不同的状态,早上起来精神饱满,中文想睡觉,下午又渐渐恢复,晚上可能精神更旺也可能耗费体力只想睡觉,这一天中就对应着不同的状态.或 ...

  • 设计模式(二十二)——状态模式(APP抽奖活动+借贷平台源码剖析)

    24.1 APP 抽奖活动问题 请编写程序完成 APP 抽奖活动 具体要求如下: 1) 假如每参加一次这个活动要扣除用户 50 积分,中奖概率是 10% 2) 奖品数量固定,抽完就不能抽奖 3) 活动 ...

  • 设计模式-行为型-访问者模式

    访问者模式(Vistor): 访问者模式的官方定义是这样的:表示一个作用于某对象结构中的各元素的操作,它使你可以在不改变各元素类的前提下定义作用于这些元素的新操作.官方的东西总是晦涩难懂的,那么我们现 ...

  • 设计模式-行为型-模板模式

    模板模式(Template): 提到模板,可能大多数人想到的是"简历模板"."论文模板"等,比如我们要写简历时,会从网上下载一份漂亮的简历模板,其格式是固定的, ...

  • 设计模式-创建型-建造者模式

    引言: 无论是在现实世界中还是在软件系统中,都存在一些复杂的对象,它们拥有多个组成部分,如汽车,它包括车轮.底盘.发动机.方向盘等各种部件.而对于大部分用户而言,无须知道这些部件的装配细节,也几乎不会 ...

  • 设计模式-创建型-工厂模式

    工厂设计模式: 顾名思义,该模式是用来生产对象的.在面向对象的设计模式中,万物皆对象,若使用new来创建对象,就会对该对象产生强耦合,假如我们需要更换该对象,那么使用该对象的对象都需要进行修改,这显然 ...

  • PHP设计模式之状态模式

    PHP设计模式之状态模式 状态模式从字面上其实并不是很好理解.这里的状态是什么意思呢?保存状态?那不就是备忘录模式了.其实,这里的状态是类的状态,通过改变类的某个状态,让这个类感觉像是换了一个类一样. ...

  • [PHP小课堂]PHP设计模式之状态模式

    [PHP小课堂]PHP设计模式之状态模式 关注公众号:[硬核项目经理]获取最新文章 添加微信/QQ好友:[DarkMatterZyCoder/149844827]免费得PHP.项目管理学习资料

  • 设计模式-行为型-中介者模式

    中介者模式(Mediator): 在现实生活中,有很多中介者模式的身影,例如QQ游戏平台,聊天室.QQ群.短信平台和房产中介.不论是QQ游戏还是QQ群,它们都是充当一个中间平台,QQ用户可以登录这个中 ...

  • 设计模式-创建型-抽象工厂模式

    前一章节,我们介绍了简单工厂模式以及工厂方法模式,但是这两种模式都存在一定的局限性,只能生产某一类型下的某一种产品,如果需求变更,同类型下出现了不同的产品,比如芝士披萨不仅有口味上的不同,同时存在外观 ...