首页 > 代码库 > 设计模式之命令模式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 }
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 }
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
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 }
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 }
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 }
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 }
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 }
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