首页 > 代码库 > 设计模式之命令模式20170719

设计模式之命令模式20170719

行为型设计模式之命令模式:

一、含义

将请求(命令)封装成一个对象(内部有接收者对象,以及按照具体命令执行接收者操作的方法),传递给调用者,由调用者执行具体命令。

也就是把一个动作的执行分为执行对象(接收者角色)、执行行为(命令角色),让两者相互独立而不相互影响,实现对动作解耦

 

二、代码说明

1.主要有三个角色

1)接收者角色

该角色就是干活的角色,被命令角色调用,其操作按具体命令的要求执行

2)命令角色

需要执行的所有命令都在这里声明,同时接收者所有的对象都在这里(接收者封装在这里,防止高层模块对底层的依赖)

3)调用者角色

接收到命令(请求),并执行命令

 

2.在用C实现过程中也是参考这种思想,以客户给项目组发布命令举例,具体实现如下:

1)命令模式使用场景:

技术分享
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     CommandPatternUsage.c
 5 * Description        :     命令模式的使用
 6 
 7 book@book-desktop:/work/projects/test/DesignPatterns/CommandPattern$ gcc -o CommandPatternUsage CodeGroup.c PageGroup.c RequirementGroup.c CommandPattern.c AddRequirementCommand.c DeletePageCommand.c CommandPatternUsage.c
 8 book@book-desktop:/work/projects/test/DesignPatterns/CommandPattern$ ./CommandPatternUsage 
 9 客户要求增加一项需求:
10 找到需求组。。。
11 客户要求增加一项需求。。。
12 客户要求给出需求变更计划。。。
13 客户要求删除一个页面:
14 找到美工组。。。
15 客户要求删除一项页面。。。
16 客户要求给出页面变更计划。。。
17 
18 * Created            :     2017.07.18.
19 * Author            :     Yu Weifeng
20 * Function List         :     
21 * Last Modified     :     
22 * History            :     
23 ******************************************************************************/
24 #include"stdio.h"
25 #include"malloc.h"
26 #include"stdlib.h"
27 #include"string.h"
28 #include"CommandPattern.h"
29 
30 
31 
32 
33 /*****************************************************************************
34 -Fuction        : main
35 -Description    : 
36 -Input            : 
37 -Output         : 
38 -Return         : 
39 * Modify Date      Version         Author           Modification
40 * -----------------------------------------------
41 * 2017/07/18    V1.0.0         Yu Weifeng       Created
42 ******************************************************************************/
43 int main(int argc,char **argv)
44 {
45     printf("客户要求增加一项需求:\r\n");
46     T_Command tCommand=newAddRequirementCommand;
47     g_tInvoker.SetCommand(&tCommand);
48     g_tInvoker.Action();
49     
50     printf("客户要求删除一个页面:\r\n");
51     tCommand=(T_Command)newDeletePageCommand;
52     g_tInvoker.SetCommand(&tCommand);
53     g_tInvoker.Action();
54 
55     return 0;
56 }
CommandPatternUsage.c

2)被调用者:

技术分享
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     CommandPattern.c
 5 * Description        :     命令模式
 6                         本文件是调用者(接收命令、执行命令)的实现
 7                         (以客户给项目组发布命令举例,即项目接头人
 8                         ,接收客户发过来的命令,执行客户的命令)
 9                                     
10 * Created            :     2017.07.18.
11 * Author            :     Yu Weifeng
12 * Function List         :     
13 * Last Modified     :     
14 * History            :     
15 ******************************************************************************/
16 #include"stdio.h"
17 #include"malloc.h"
18 #include"stdlib.h"
19 #include"string.h"
20 #include"CommandPattern.h"
21 
22 static void SetCommand(T_Command *i_ptCommand);
23 static void Action();
24 
25 static T_Command g_tCommand;//私有权限
26 
27 
28 const T_Invoker g_tInvoker={//单例,一个项目一个接头人
29     .SetCommand    =SetCommand,
30     .Action        =Action,
31 };
32 /*****************************************************************************
33 -Fuction        : SetCommand
34 -Description    : 公有函数
35 -Input            : 
36 -Output         : 
37 -Return         : 
38 * Modify Date      Version         Author           Modification
39 * -----------------------------------------------
40 * 2017/07/17      V1.0.0         Yu Weifeng       Created
41 ******************************************************************************/
42 static void SetCommand(T_Command *i_ptCommand)
43 {
44     memcpy(&g_tCommand,i_ptCommand,sizeof(T_Command));
45 }
46 /*****************************************************************************
47 -Fuction        : SetCommand
48 -Description    : 公有函数
49 -Input            : 
50 -Output         : 
51 -Return         : 
52 * Modify Date      Version         Author           Modification
53 * -----------------------------------------------
54 * 2017/07/17      V1.0.0         Yu Weifeng       Created
55 ******************************************************************************/
56 static void Action()
57 {
58     g_tCommand.Execute(&g_tCommand);
59 }
CommandPattern.c
技术分享
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     CommandPattern.h
 5 * Description        :     命令模式
 6                                     
 7 * Created            :     2017.07.18.
 8 * Author            :     Yu Weifeng
 9 * Function List         :     
10 * Last Modified     :     
11 * History            :     
12 ******************************************************************************/
13 #ifndef COMMAND_PATTERN_H
14 #define COMMAND_PATTERN_H
15 
16 
17 
18 typedef struct Group
19 {
20     void (*Find)();
21     void (*Add)();
22     void (*Delete)();
23     void (*Change)();
24     void (*Plan)();
25 }T_Group;
26 
27 typedef struct Command
28 {
29     T_Group tRequirementGroup;
30     T_Group tCodeGroup;
31     T_Group tPageGroup;
32     void (*Execute)(struct Command *i_ptThis);
33 }T_Command;
34 
35 typedef struct Invoker
36 {
37     void (*SetCommand)(T_Command *i_ptCommand);
38     void (*Action)();
39 }T_Invoker;
40 
41 
42 void RequirementGroupFind();
43 void RequirementGroupAdd();
44 void RequirementGroupDelete();
45 void RequirementGroupChange();
46 void RequirementGroupPlan();
47 #define newRequirementGroup {RequirementGroupFind,RequirementGroupAdd,RequirementGroupDelete,48                              RequirementGroupChange,RequirementGroupPlan}
49 
50 void CodeGroupFind();
51 void CodeGroupAdd();
52 void CodeGroupDelete();
53 void CodeGroupChange();
54 void CodeGroupPlan();
55 #define newCodeGroup {CodeGroupFind,CodeGroupAdd,CodeGroupDelete,CodeGroupChange,CodeGroupPlan}
56 
57 void PageGroupFind();
58 void PageGroupAdd();
59 void PageGroupDelete();
60 void PageGroupChange();
61 void PageGroupPlan();
62 #define newPageGroup {PageGroupFind,PageGroupAdd,PageGroupDelete,PageGroupChange,PageGroupPlan}
63 
64 
65 
66 void AddRequirementCommandExecute(T_Command *i_ptThis);
67 #define newAddRequirementCommand {newRequirementGroup,newCodeGroup,newPageGroup,AddRequirementCommandExecute}
68 
69 void DeletePageCommandExecute(T_Command *i_ptThis);
70 #define newDeletePageCommand {newRequirementGroup,newCodeGroup,newPageGroup,DeletePageCommandExecute}
71 
72 
73 extern const T_Invoker g_tInvoker;//单例,一个项目一个接头人
74 
75 
76 
77 #endif
CommandPattern.h
技术分享
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     AddRequirementCommand.c
 5 * Description        :     增加需求命令
 6                         本文件是命令的具体实现类
 7 * Created            :     2017.07.18.
 8 * Author            :     Yu Weifeng
 9 * Function List         :     
10 * Last Modified     :     
11 * History            :     
12 ******************************************************************************/
13 #include"stdio.h"
14 #include"malloc.h"
15 #include"stdlib.h"
16 #include"string.h"
17 #include"CommandPattern.h"
18 
19 /*****************************************************************************
20 -Fuction        : RequirementGroupFind
21 -Description    : 
22 -Input            : 
23 -Output         : 
24 -Return         : 
25 * Modify Date      Version         Author           Modification
26 * -----------------------------------------------
27 * 2017/07/18      V1.0.0         Yu Weifeng       Created
28 ******************************************************************************/
29 void AddRequirementCommandExecute(T_Command *i_ptThis)
30 {
31     i_ptThis->tRequirementGroup.Find();
32     i_ptThis->tRequirementGroup.Add();
33     i_ptThis->tRequirementGroup.Plan();
34 }
AddRequirementCommand.c
技术分享
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     DeletePageCommand.c
 5 * Description        :     删除页面命令
 6                         本文件是命令的具体实现类
 7 * Created            :     2017.07.18.
 8 * Author            :     Yu Weifeng
 9 * Function List         :     
10 * Last Modified     :     
11 * History            :     
12 ******************************************************************************/
13 #include"stdio.h"
14 #include"malloc.h"
15 #include"stdlib.h"
16 #include"string.h"
17 #include"CommandPattern.h"
18 
19 /*****************************************************************************
20 -Fuction        : DeletePageCommandExecute
21 -Description    : 
22 -Input            : 
23 -Output         : 
24 -Return         : 
25 * Modify Date      Version         Author           Modification
26 * -----------------------------------------------
27 * 2017/07/18      V1.0.0         Yu Weifeng       Created
28 ******************************************************************************/
29 void DeletePageCommandExecute(T_Command *i_ptThis)
30 {
31     i_ptThis->tPageGroup.Find();
32     i_ptThis->tPageGroup.Delete();
33     i_ptThis->tPageGroup.Plan();
34 }
DeletePageCommand.c
技术分享
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     RequirementGroup.c
 5 * Description        :     需求组
 6                         本文件是项目成员组的具体实现类(需求组)
 7 * Created            :     2017.07.18.
 8 * Author            :     Yu Weifeng
 9 * Function List         :     
10 * Last Modified     :     
11 * History            :     
12 ******************************************************************************/
13 #include"stdio.h"
14 #include"malloc.h"
15 #include"stdlib.h"
16 #include"string.h"
17 #include"CommandPattern.h"
18 
19 /*****************************************************************************
20 -Fuction        : RequirementGroupFind
21 -Description    : 
22 -Input            : 
23 -Output         : 
24 -Return         : 
25 * Modify Date      Version         Author           Modification
26 * -----------------------------------------------
27 * 2017/07/18      V1.0.0         Yu Weifeng       Created
28 ******************************************************************************/
29 void RequirementGroupFind()
30 {
31     printf("找到需求组。。。\r\n");
32 }
33 
34 /*****************************************************************************
35 -Fuction        : RequirementGroupAdd
36 -Description    : 
37 -Input            : 
38 -Output         : 
39 -Return         : 
40 * Modify Date      Version         Author           Modification
41 * -----------------------------------------------
42 * 2017/07/18      V1.0.0         Yu Weifeng       Created
43 ******************************************************************************/
44 void RequirementGroupAdd()
45 {
46     printf("客户要求增加一项需求。。。\r\n");
47 }
48 
49 /*****************************************************************************
50 -Fuction        : RequirementGroupDelete
51 -Description    : 
52 -Input            : 
53 -Output         : 
54 -Return         : 
55 * Modify Date      Version         Author           Modification
56 * -----------------------------------------------
57 * 2017/07/18      V1.0.0         Yu Weifeng       Created
58 ******************************************************************************/
59 void RequirementGroupDelete()
60 {
61     printf("客户要求删除一项需求。。。\r\n");
62 }
63 
64 /*****************************************************************************
65 -Fuction        : RequirementGroupChange
66 -Description    : 
67 -Input            : 
68 -Output         : 
69 -Return         : 
70 * Modify Date      Version         Author           Modification
71 * -----------------------------------------------
72 * 2017/07/18      V1.0.0         Yu Weifeng       Created
73 ******************************************************************************/
74 void RequirementGroupChange()
75 {
76     printf("客户要求修改一项需求。。。\r\n");
77 }
78 
79 /*****************************************************************************
80 -Fuction        : RequirementGroupPlan
81 -Description    : 
82 -Input            : 
83 -Output         : 
84 -Return         : 
85 * Modify Date      Version         Author           Modification
86 * -----------------------------------------------
87 * 2017/07/18      V1.0.0         Yu Weifeng       Created
88 ******************************************************************************/
89 void RequirementGroupPlan()
90 {
91     printf("客户要求给出需求变更计划。。。\r\n");
92 }
RequirementGroup.c
技术分享
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     CodeGroup.c
 5 * Description        :     代码组
 6                         本文件是项目成员组的具体实现类(代码组)
 7 * Created            :     2017.07.18.
 8 * Author            :     Yu Weifeng
 9 * Function List         :     
10 * Last Modified     :     
11 * History            :     
12 ******************************************************************************/
13 #include"stdio.h"
14 #include"malloc.h"
15 #include"stdlib.h"
16 #include"string.h"
17 #include"CommandPattern.h"
18 
19 /*****************************************************************************
20 -Fuction        : CodeGroupFind
21 -Description    : 
22 -Input            : 
23 -Output         : 
24 -Return         : 
25 * Modify Date      Version         Author           Modification
26 * -----------------------------------------------
27 * 2017/07/18      V1.0.0         Yu Weifeng       Created
28 ******************************************************************************/
29 void CodeGroupFind()
30 {
31     printf("找到代码组。。。\r\n");
32 }
33 
34 /*****************************************************************************
35 -Fuction        : CodeGroupAdd
36 -Description    : 
37 -Input            : 
38 -Output         : 
39 -Return         : 
40 * Modify Date      Version         Author           Modification
41 * -----------------------------------------------
42 * 2017/07/18      V1.0.0         Yu Weifeng       Created
43 ******************************************************************************/
44 void CodeGroupAdd()
45 {
46     printf("客户要求增加一项功能。。。\r\n");
47 }
48 
49 /*****************************************************************************
50 -Fuction        : CodeGroupDelete
51 -Description    : 
52 -Input            : 
53 -Output         : 
54 -Return         : 
55 * Modify Date      Version         Author           Modification
56 * -----------------------------------------------
57 * 2017/07/18      V1.0.0         Yu Weifeng       Created
58 ******************************************************************************/
59 void CodeGroupDelete()
60 {
61     printf("客户要求删除一项功能。。。\r\n");
62 }
63 
64 /*****************************************************************************
65 -Fuction        : CodeGroupChange
66 -Description    : 
67 -Input            : 
68 -Output         : 
69 -Return         : 
70 * Modify Date      Version         Author           Modification
71 * -----------------------------------------------
72 * 2017/07/18      V1.0.0         Yu Weifeng       Created
73 ******************************************************************************/
74 void CodeGroupChange()
75 {
76     printf("客户要求修改一项功能。。。\r\n");
77 }
78 
79 /*****************************************************************************
80 -Fuction        : CodeGroupPlan
81 -Description    : 
82 -Input            : 
83 -Output         : 
84 -Return         : 
85 * Modify Date      Version         Author           Modification
86 * -----------------------------------------------
87 * 2017/07/18      V1.0.0         Yu Weifeng       Created
88 ******************************************************************************/
89 void CodeGroupPlan()
90 {
91     printf("客户要求给出代码变更计划。。。\r\n");
92 }
CodeGroup.c
技术分享
 1 /*****************************************************************************
 2 * Copyright (C) 2017-2018 Hanson Yu  All rights reserved.
 3 ------------------------------------------------------------------------------
 4 * File Module        :     PageGroup.c
 5 * Description        :     美工组
 6                         本文件是项目成员组的具体实现类(美工组)
 7 * Created            :     2017.07.18.
 8 * Author            :     Yu Weifeng
 9 * Function List         :     
10 * Last Modified     :     
11 * History            :     
12 ******************************************************************************/
13 #include"stdio.h"
14 #include"malloc.h"
15 #include"stdlib.h"
16 #include"string.h"
17 #include"CommandPattern.h"
18 
19 /*****************************************************************************
20 -Fuction        : PageGroupFind
21 -Description    : 
22 -Input            : 
23 -Output         : 
24 -Return         : 
25 * Modify Date      Version         Author           Modification
26 * -----------------------------------------------
27 * 2017/07/18      V1.0.0         Yu Weifeng       Created
28 ******************************************************************************/
29 void PageGroupFind()
30 {
31     printf("找到美工组。。。\r\n");
32 }
33 
34 /*****************************************************************************
35 -Fuction        : PageGroupAdd
36 -Description    : 
37 -Input            : 
38 -Output         : 
39 -Return         : 
40 * Modify Date      Version         Author           Modification
41 * -----------------------------------------------
42 * 2017/07/18      V1.0.0         Yu Weifeng       Created
43 ******************************************************************************/
44 void PageGroupAdd()
45 {
46     printf("客户要求增加一项页面。。。\r\n");
47 }
48 
49 /*****************************************************************************
50 -Fuction        : PageGroupDelete
51 -Description    : 
52 -Input            : 
53 -Output         : 
54 -Return         : 
55 * Modify Date      Version         Author           Modification
56 * -----------------------------------------------
57 * 2017/07/18      V1.0.0         Yu Weifeng       Created
58 ******************************************************************************/
59 void PageGroupDelete()
60 {
61     printf("客户要求删除一项页面。。。\r\n");
62 }
63 
64 /*****************************************************************************
65 -Fuction        : PageGroupChange
66 -Description    : 
67 -Input            : 
68 -Output         : 
69 -Return         : 
70 * Modify Date      Version         Author           Modification
71 * -----------------------------------------------
72 * 2017/07/18      V1.0.0         Yu Weifeng       Created
73 ******************************************************************************/
74 void PageGroupChange()
75 {
76     printf("客户要求修改一项页面。。。\r\n");
77 }
78 
79 /*****************************************************************************
80 -Fuction        : PageGroupPlan
81 -Description    : 
82 -Input            : 
83 -Output         : 
84 -Return         : 
85 * Modify Date      Version         Author           Modification
86 * -----------------------------------------------
87 * 2017/07/18      V1.0.0         Yu Weifeng       Created
88 ******************************************************************************/
89 void PageGroupPlan()
90 {
91     printf("客户要求给出页面变更计划。。。\r\n");
92 }
PageGroup.c

 

3)执行结果:

book@book-desktop:/work/projects/test/DesignPatterns/CommandPattern$ gcc -o CommandPatternUsage CodeGroup.c PageGroup.c RequirementGroup.c CommandPattern.c AddRequirementCommand.c DeletePageCommand.c CommandPatternUsage.c

book@book-desktop:/work/projects/test/DesignPatterns/CommandPattern$ ./CommandPatternUsage

客户要求增加一项需求:

找到需求组。。。

客户要求增加一项需求。。。

客户要求给出需求变更计划。。。

客户要求删除一个页面:

找到美工组。。。

客户要求删除一项页面。。。

客户要求给出页面变更计划。。。

 

 

4)详细代码:

https://github.com/fengweiyu/DesignThinking/tree/master/DesignPatterns/BehavioralDesignPatterns/CommandPattern

 

三、使用场景

1.只要认为是命令的地方就可以采用命令模式

例如,在GUI开发中,一个按钮的点击是一个命令,可以采用命令模式。模拟Dos命令时,可以采用命令模式。触发-反馈机制的处理,可以采用命令模式

2.封装命令,使请求者与接收者(执行者)解耦,适用于解耦两个有紧耦合关系的对象场景或者多命令多撤销的场景

 

四、优点

1.类间解耦

调用者和接收者之间没有任何依赖关系,调用者实现功能只需调用Command抽象类(接口当传入参数)的execute方法就可以,不需要了解到底是哪个接收者执行。

2.可扩展性

Command的子类可以非常容易地扩展,而调用者Invoker和高层次模块不产生严重的代码耦合

3.命令模式结合其他模式会更优秀

命令模式可以结合责任链模式,实现命令族解析任务,结合模版方法模式,则可以减少Command子类的膨胀问题

 

五、缺点

如果有N个命令,Command的子类就是N个,这个类会膨胀得非常大。

 

六、命令模式与策略模式区别:

1.关注点不同

I、策略模式关注的是算法的完整性、封装性,以保证算法可以自由切换。

II、命令模式则关注的是解耦问题,如何让请求者(调用者)和接收者(执行者)解耦是它需要首先解决的,解耦的要求就是把请求的内容封装为一个个的命令(由接收者执行)。

2.角色功能不同

I、策略模式中的具体算法是负责一个完整算法逻辑,它是一个不可拆分的原子业务单元,一旦变更就是对算法整体的变更。

II、命令模式中的接收者对命令负责,而与请求者(调用者)无关。命令模式中的接收者只要符合六大设计原则,完全不用关心它是否完成了一个具体逻辑。

3,使用场景不同

I、策略模式适用于算法要求变换的场景

II、命令模式适用于解耦两个有紧耦合关系的对象场景或者多命令多撤销的场景

 

设计模式之命令模式20170719