设计模式之状态模式20170712

Posted yuweifeng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之状态模式20170712相关的知识,希望对你有一定的参考价值。

行为型设计模式之状态模式:

一、含义

为每个状态创建与之对应的类(对应的每个类实现同一个接口或继承同一个抽象类,便于统一处理),并且再通过一个类切换状态

 

 

二、代码说明

1.一般包含三个角色抽象状态角色,具体状态角色,以及环境(上下文)角色(负责具体状态的切换)。

具体步骤:

1)定义环境角色,并初始化状态

2)通过环境角色执行行为,同时也就是对应状态的行为被执行

3)对应状态的行为的执行分为两种情况:

I、对应状态对应行为执行后,环境角色继续执行行为,调用的还是此状态,此状态的下一个行为(下一状态的行为)被执行,执行中会设置下一态(设置下一态一般都放在抽象父类中,同时由于是继承设置下一态时,也要把对应的环境对象设置进去(继承导致每个子类都有对应的环境类的引用),这样下一个状态对象才能调用环境类中的函数),设置完后再执行对应的下一个行为

II、或对应状态对应行为(函数)执行中,先执行对应的操作,然后设置下一态(显然也要把对应的环境对象设置进去),这样环境角色再次执行行为就是调用下一态的行为(函数)了,而不是还停留在本状态。

两种情况均可以,二选一即可,但是显然第二种方式更简单一点,但对外来看没有差异。

4)接下来再次调用环境角色执行行为,由于前面设置了状态,此时执行的就是下一状态的行为

5)不断调用环境角色执行行为,知道所有的状态行为执行完毕

6)扩展:不断调用环境角色执行行为可以使用建造者模式组装起来进行优化

 

2.在用C实现过程中也是参考这种思想,不过设置下一态不使用继承的方式,以电梯运行状态举例,状态迁移表如下:

 

具体实现如下:

1)状态模式使用场景:

 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     StatePatternUsage.c
 5 * Description        :     状态模式的使用
 6 
 7 book@book-desktop:/work/projects/test/DesignPatterns$ gcc -o StatePatternUsage RunningState.c StoppingState.c  OpenningState.c ClosingState.c StatePattern.c StatePatternUsage.c 
 8 book@book-desktop:/work/projects/test/DesignPatterns$ ./StatePatternUsage 
 9 Lift door open!
10 Lift door close!
11 Lift door run!
12 Lift door stop!
13 
14 * Created            :     2017.07.12.
15 * Author            :     Yu Weifeng
16 * Function List         :     
17 * Last Modified     :     
18 * History            :     
19 ******************************************************************************/
20 #include"stdio.h"
21 #include"malloc.h"
22 #include"stdlib.h"
23 #include"string.h"
24 #include"StatePattern.h"
25 
26 
27 
28 
29 /*****************************************************************************
30 -Fuction        : main
31 -Description    : 
32 -Input            : 
33 -Output         : 
34 -Return         : 
35 * Modify Date      Version         Author           Modification
36 * -----------------------------------------------
37 * 2017/07/12    V1.0.0         Yu Weifeng       Created
38 ******************************************************************************/
39 int main(int argc,char **argv)
40 {
41      T_StateContext tStateContext=newStateContext;
42     T_State tState=newClosingState;
43     tStateContext.SetState(&tState);
44 
45     tStateContext.Open();
46     tStateContext.Close();
47     tStateContext.Run();
48     tStateContext.Stop();
49 
50     
51     return 0;
52 }
StatePatternUsage.c

隐藏(封装)了状态的变化过程,它的切换引起了行为的变化。对外来说,我们只看到行为的发生改变,而不用知道是状态变化引起的。

2)被调用者:

I、环境(上下文)角色(负责具体状态的切换):

  1 /*****************************************************************************
  2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
  3 ------------------------------------------------------------------------------
  4 * File Module        :     StatePattern.c
  5 * Description        :     状态模式
  6                         对各个状态进行管理,也可以改名为StateManage.c
  7                         为统一名称,本文件也是状态模式的核心故还是
  8                         命名为StatePattern.c
  9                         
 10                         
 11 * Created            :     2017.07.12.
 12 * Author            :     Yu Weifeng
 13 * Function List         :     
 14 * Last Modified     :     
 15 * History            :     
 16 ******************************************************************************/
 17 #include"stdio.h"
 18 #include"malloc.h"
 19 #include"stdlib.h"
 20 #include"string.h"
 21 #include"StatePattern.h"
 22 
 23 
 24 
 25 static T_State g_tState;
 26 
 27 /*****************************************************************************
 28 -Fuction        : SetState
 29 -Description    : 公有函数
 30 -Input            : 
 31 -Output         : 
 32 -Return         : 
 33 * Modify Date      Version         Author           Modification
 34 * -----------------------------------------------
 35 * 2017/07/12      V1.0.0         Yu Weifeng       Created
 36 ******************************************************************************/
 37 void SetState(T_State *i_ptState)
 38 {
 39     memcpy(&g_tState,i_ptState,sizeof(T_State));
 40 }
 41 
 42 /*****************************************************************************
 43 -Fuction        : SetState
 44 -Description    : 公有函数
 45 -Input            : 
 46 -Output         : 
 47 -Return         : 
 48 * Modify Date      Version         Author           Modification
 49 * -----------------------------------------------
 50 * 2017/07/12      V1.0.0         Yu Weifeng       Created
 51 ******************************************************************************/
 52 void GetState(T_State *o_ptState)
 53 {
 54     memcpy(o_ptState,&g_tState,sizeof(T_State));
 55 }
 56 /*****************************************************************************
 57 -Fuction        : Open
 58 -Description    : 公有函数
 59 -Input            : 
 60 -Output         : 
 61 -Return         : 
 62 * Modify Date      Version         Author           Modification
 63 * -----------------------------------------------
 64 * 2017/07/12      V1.0.0         Yu Weifeng       Created
 65 ******************************************************************************/
 66 void Open()
 67 {
 68     g_tState.Open();
 69 }
 70 /*****************************************************************************
 71 -Fuction        : Close
 72 -Description    : 公有函数
 73 -Input            : 
 74 -Output         : 
 75 -Return         : 
 76 * Modify Date      Version         Author           Modification
 77 * -----------------------------------------------
 78 * 2017/07/12      V1.0.0         Yu Weifeng       Created
 79 ******************************************************************************/
 80 void Close()
 81 {
 82     g_tState.Close();
 83 }
 84 /*****************************************************************************
 85 -Fuction        : Run
 86 -Description    : 公有函数
 87 -Input            : 
 88 -Output         : 
 89 -Return         : 
 90 * Modify Date      Version         Author           Modification
 91 * -----------------------------------------------
 92 * 2017/07/12      V1.0.0         Yu Weifeng       Created
 93 ******************************************************************************/
 94 void Run()
 95 {
 96     g_tState.Run();
 97 }
 98 /*****************************************************************************
 99 -Fuction        : Stop
100 -Description    : 公有函数
101 -Input            : 
102 -Output         : 
103 -Return         : 
104 * Modify Date      Version         Author           Modification
105 * -----------------------------------------------
106 * 2017/07/12      V1.0.0         Yu Weifeng       Created
107 ******************************************************************************/
108 void Stop()
109 {
110     g_tState.Stop();
111 }
StatePattern.c
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     StatePattern.h
 5 * Description        :     状态模式
 6                         对各个状态进行管理,也可以改名为StateManage.h
 7                         为统一名称,本文件也是状态模式的核心故还是
 8                         命名为StatePattern.h
 9 * Created            :     2017.07.12.
10 * Author            :     Yu Weifeng
11 * Function List         :     
12 * Last Modified     :     
13 * History            :     
14 ******************************************************************************/
15 #ifndef STATE_PATTERN_H
16 #define STATE_PATTERN_H
17 
18 
19 
20 typedef struct State//以电梯运行四种状态举例
21 {
22 //    T_FatherState tFatherState;//继承父类,由于c中没有super关键字
23     void (*Open)();//子类内部函数要初始化后才能使用父类的,除非初始化后再设置状态
24     void (*Close)();//为了封装,内部函数就直接调用上下文类设置状态,不使用继承
25     void (*Run)();//也是由于C中只有一个上下文Context,才可以这么做
26     void (*Stop)();
27 }T_State;//对各种状态的行为进行抽象后的抽象接口
28 
29 typedef struct FatherState//抽象出子类统一会设置上下状态函数
30 {
31 //void (*SetContext)(T_StateContext *i_ptStateContext);//由于面向对象语言中
32 //每个子类new的时候都会有一个Context引用产生,切换状态时,
33 //就需要要设置context(下一个子类才能使用context来设置下一态),
34 //而C中只有一个,所以不需要
35     void (*SetState)(T_State *i_ptState);//供状态设置下一状态使用
36     void (*GetState)(T_State *o_ptState);
37 }T_FatherState;
38 
39 typedef struct StateContext//因为状态需要切换所以需要上下文类
40 {
41     void (*SetState)(T_State *i_ptState);//供状态设置下一状态使用
42     void (*GetState)(T_State *o_ptState);
43     void (*Open)();//内部不加入状态的静态对象,因为增加的话结构体会过于臃肿
44     void (*Close)();//而且不加入使用更灵活,同时C的对象都是函数指针不费内存
45     void (*Run)();
46     void (*Stop)();
47 }T_StateContext;
48 
49 
50 
51 
52 
53 
54 void SetState(T_State *i_ptState);
55 void GetState(T_State *o_ptState);
56 void Open();
57 void Close();
58 void Run();
59 void Stop();
60 #define newStateContext {SetState,GetState,Open,Close,Run,Stop};
61 
62 
63 
64 
65 
66 void RunningStateOpen();
67 void RunningStateClose();
68 void RunningStateRun();
69 void RunningStateStop();
70 #define newRunningState {RunningStateOpen,RunningStateClose,RunningStateRun,RunningStateStop}
71 
72 void StoppingStateOpen();
73 void StoppingStateClose();
74 void StoppingStateRun();
75 void StoppingStateStop();
76 #define newStoppingState {StoppingStateOpen,StoppingStateClose,StoppingStateRun,StoppingStateStop}
77 
78 void ClosingStateOpen();
79 void ClosingStateClose();
80 void ClosingStateRun();
81 void ClosingStateStop();
82 #define newClosingState {ClosingStateOpen,ClosingStateClose,ClosingStateRun,ClosingStateStop}
83 
84 void OpenningStateOpen();
85 void OpenningStateClose();
86 void OpenningStateRun();
87 void OpenningStateStop();
88 #define newOpenningState {OpenningStateOpen,OpenningStateClose,OpenningStateRun,OpenningStateStop}
89 
90 
91 
92 #endif
StatePattern.h

II、具体状态角色(各个状态实现同一个接口)

 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     ClosingState.c
 5 * Description        :     关闭状态下的各种行为
 6 * Created            :     2017.07.12.
 7 * Author            :     Yu Weifeng
 8 * Function List         :     
 9 * Last Modified     :     
10 * History            :     
11 ******************************************************************************/
12 #include"stdio.h"
13 #include"malloc.h"
14 #include"stdlib.h"
15 #include"string.h"
16 #include"StatePattern.h"
17 
18 
19 
20 
21 
22 /*****************************************************************************
23 -Fuction        : ClosingStateOpen
24 -Description    : 公有函数
25 -Input            : 
26 -Output         : 
27 -Return         : 
28 * Modify Date      Version         Author           Modification
29 * -----------------------------------------------
30 * 2017/07/12      V1.0.0         Yu Weifeng       Created
31 ******************************************************************************/
32 void ClosingStateOpen()
33 {
34     T_StateContext tStateContext=newStateContext;
35     T_State tState=newOpenningState;
36     tStateContext.SetState(&tState);//切换状态
37     tStateContext.GetState(&tState);
38     tState.Open();//执行,逻辑上过度 到下一态
39 }
40 /*****************************************************************************
41 -Fuction        : ClosingStateClose
42 -Description    : 公有函数
43 -Input            : 
44 -Output         : 
45 -Return         : 
46 * Modify Date      Version         Author           Modification
47 * -----------------------------------------------
48 * 2017/07/12      V1.0.0         Yu Weifeng       Created
49 ******************************************************************************/
50 void ClosingStateClose()
51 {
52     printf("Lift door close!\\r\\n");
53 }
54 /*****************************************************************************
55 -Fuction        : ClosingStateRun
56 -Description    : 公有函数
57 -Input            : 
58 -Output         : 
59 -Return         : 
60 * Modify Date      Version         Author           Modification
61 * -----------------------------------------------
62 * 2017/07/12      V1.0.0         Yu Weifeng       Created
63 ******************************************************************************/
64 void ClosingStateRun()
65 {
66     T_StateContext tStateContext=newStateContext;
67     T_State tState=newRunningState;
68     tStateContext.SetState(&tState);//切换状态
69     tStateContext.GetState(&tState);
70     tState.Run();//执行,逻辑上过度 到下一态
71 }
72 /*****************************************************************************
73 -Fuction        : ClosingStateStop
74 -Description    : 公有函数
75 -Input            : 
76 -Output         : 
77 -Return         : 
78 * Modify Date      Version         Author           Modification
79 * -----------------------------------------------
80 * 2017/07/12      V1.0.0         Yu Weifeng       Created
81 ******************************************************************************/
82 void ClosingStateStop()
83 {
84     T_StateContext tStateContext=newStateContext;
85     T_State tState=newStoppingState;
86     tStateContext.SetState(&tState);//切换状态
87     tStateContext.GetState(&tState);
88     tState.Stop();//执行,逻辑上过度 到下一态
89 }
ClosingState.c
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     OpenningState.c
 5 * Description        :     开门状态下的各种行为
 6 * Created            :     2017.07.12.
 7 * Author            :     Yu Weifeng
 8 * Function List         :     
 9 * Last Modified     :     
10 * History            :     
11 ******************************************************************************/
12 #include"stdio.h"
13 #include"malloc.h"
14 #include"stdlib.h"
15 #include"string.h"
16 #include"StatePattern.h"
17 
18 
19 
20 
21 
22 /*****************************************************************************
23 -Fuction        : OpenningStateOpen
24 -Description    : 公有函数
25 -Input            : 
26 -Output         : 
27 -Return         : 
28 * Modify Date      Version         Author           Modification
29 * -----------------------------------------------
30 * 2017/07/12      V1.0.0         Yu Weifeng       Created
31 ******************************************************************************/
32 void OpenningStateOpen()
33 {
34     printf("Lift door open!\\r\\n");
35 }
36 /*****************************************************************************
37 -Fuction        : OpenningStateClose
38 -Description    : 公有函数
39 -Input            : 
40 -Output         : 
41 -Return         : 
42 * Modify Date      Version         Author           Modification
43 * -----------------------------------------------
44 * 2017/07/12      V1.0.0         Yu Weifeng       Created
45 ******************************************************************************/
46 void OpenningStateClose()
47 {
48     T_StateContext tStateContext=newStateContext;
49     T_State tState=newClosingState;
50     tStateContext.SetState(&tState);//切换状态
51     tStateContext.GetState(&tState);
52     tState.Close();//执行,逻辑上过度 到下一态
53 }
54 /*****************************************************************************
55 -Fuction        : OpenningStateRun
56 -Description    : 门开肯定不运行
57 -Input            : 
58 -Output         : 
59 -Return         : 
60 * Modify Date      Version         Author           Modification
61 * -----------------------------------------------
62 * 2017/07/12      V1.0.0         Yu Weifeng       Created
<

以上是关于设计模式之状态模式20170712的主要内容,如果未能解决你的问题,请参考以下文章

行为型模式之 状态模式

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

Head First设计模式之状态模式

设计模式之状态模式

java 之 状态模式(大话设计模式)

JUC并发编程 共享模式之工具 JUC CountdownLatch(倒计时锁) -- CountdownLatch应用(等待多个线程准备完毕( 可以覆盖上次的打印内)等待多个远程调用结束)(代码片段