设计模式篇——命令模式


prtyaa
prtyaa 2023-12-29 21:56:59 65781
分类专栏: 资讯

项目经理的重要性

在上学的时候,老师会把一个班的同学分成几个小组,并且每个小组选出一个组长,由组长带领自己的组员共同完成一个程序的开发。参加工作后,每个项目也都会有一个项目经理的角色,他们要做的事情就是同客户沟通需求并且制定最终需求,控制成本,把控进度,分配任务等等,可见一个项目经理对整个项目组是非常重要的。那没了项目经理会怎么样呢?接下来,我们用代码来模拟这个场景,看下缺少项目经理这个角色后,会存在怎样的问题。

假设我们现在要开发一个后台管理系统,我们的成员分为需求组、美工组、代码组。整个开发流程大致是这样的:客户首先与需求组讨论需求,然后和美工组讨论页面,最后和代码组讨论实现,告诉他们修改、删除、增加各种内容等。针对这种场景,我们设计出如下类图:

 

 

类图很简单,一个抽象组类,三个具体组继承自抽象组,客户Client分别与三个组进行交互。代码清单如下。

抽象组Group:

 

 

需求组RequirementGroup:

 

 

美工组:

 

 

代码组:

 

 

整个项目的3个支柱都已经产生了,那看客户怎么和我们谈。客户刚开始提交了他们自己写的一份比较完整的需求,需求组根据这份需求写了一份分析说明说,客户看后要求增加需求。代码如下:

 

 

运行结果如下所示:

 

 

客户的需求暂时满足了,过了一段时间,客户又要求删掉一个界面,于是又有一次场景变化:

 

 

运行结果如下所示:

 

 

过了一天后,客户又把代码组叫过去,说是数据库设计有问题,然后又叫美工组过去改页面,布置了一堆的命令……这时候,问题就慢慢浮现出来了。客户每次有问题都叫一个组过去,还要分析这个问题是需求还是页面还是代码,非常不方便,还会存在把美工组叫过来说页面画的不对,但美工说需求就是这样的,于是客户又要去找需求组谈,一次次的折腾,客户肯定会烦躁的。这时,就需要我们这面选举出一位项目经理了,客户不管有什么问题都找项目经理谈,然后项目经理根据客户的问题,分配给不同的组去处理,这样就能避免出现上面的问题了。说白了,就是客户发出命令,项目经理执行命令,具体怎么执行,由谁执行,由项目经理来确定。这就是所谓的命令模式。

命令模式

将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能,这就是命令模式。

命令模式的通用类图如下:

 

 

在该类图中,有三个角色:

1. Receiver接收者角色

该角色就是干活的角色,命令传递到这里是应该被执行的,具体到我们上面的例子中就是Group的三个实现类。

2. Command命令角色

需要执行的所有命令都在这里声明。

3. Invoker调用者命令

接收到命令,并执行命令。项目经理就是这个角色。

它们的代码清单如下。

通用Receiver类:

 

 

具体接收者类:

 

 

 

 

接收者可以有N个,这要依赖业务的具体定义。

命令角色是命令模式的核心,其抽象的命令类如下:

 

 

具体的命令类也可以有N的,代码如下:

 

 

 

 

最后是调用者Invoker:

 

 

场景类:

 

 

一个完整的命令模式就此完成。

实战:利用命令模式优化例子代码

根据命令模式,我们对开头例子进行优化。首先,我们修改类图如下:

 

 

Command抽象类只有一个方法execute(),其作用就是执行命令。Invoker就相当于项目经理的角色,负责从客户那里获取需求,并按情况分配给对应的组进行处理。代码清单如下。

抽象命令类Command:

 

 

抽象类很简单,具体的子类只要重写execute方法就可以了。在一个项目中,增加需求是很常见的,那就把“增加需求”定义为一个命令AddRequirementCommand类:

 

 

同样,再定义一个删除页面命令类DeletePageCommand:

 

 

Command抽象类可以有N个子类,如增加一个功能(AddFunctionCommand)等,只要是由客户产生、时常性的行为都可以定义为一个命令,可以自行扩展。

接下来再看负责人Invoker类:

 

 

到这里,代码改造就完成了,我们模拟增加一项需求的过程:

 

 

运行结果如下所示:

 

 

如果客户要求删除一个页面呢:

 

 

运行结果如下所示:

 

 

可以看到,我们只需要修改设置命令那一行代码即可,非常简单。

命令模式的应用

命令模式具有以下优点:

1. 类间解耦

调用者角色与接收者角色之间没有任何依赖关系,调用者实现功能时只需调用Command抽象类的execute方法就可以,不需要了解到底是哪个接收者执行。

2. 可扩展性

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

命令模式也是有缺点的,就是如果有N个命令,Command的子类就是N个,这个类膨胀的非常大,需要在项目中慎重考虑使用。

实际开发中,只要你认为是命令的地方就可以采用命令模式。例如,一个按钮的点击是一个命令,就可以采用命令模式。

网站声明:如果转载,请联系本站管理员。否则一切后果自行承担。

本文链接:https://www.xckfsq.com/news/show.html?id=32322
赞同 0
评论 0 条
prtyaaL1
粉丝 1 发表 2554 + 关注 私信
上周热门
银河麒麟添加网络打印机时,出现“client-error-not-possible”错误提示  1487
银河麒麟打印带有图像的文档时出错  1405
银河麒麟添加打印机时,出现“server-error-internal-error”  1194
统信操作系统各版本介绍  1116
统信桌面专业版【如何查询系统安装时间】  1114
统信桌面专业版【全盘安装UOS系统】介绍  1068
麒麟系统也能完整体验微信啦!  1026
统信【启动盘制作工具】使用介绍  672
统信桌面专业版【一个U盘做多个系统启动盘】的方法  616
信刻全自动档案蓝光光盘检测一体机  526
本周热议
我的信创开放社区兼职赚钱历程 40
今天你签到了吗? 27
信创开放社区邀请他人注册的具体步骤如下 15
如何玩转信创开放社区—从小白进阶到专家 15
方德桌面操作系统 14
我有15积分有什么用? 13
用抖音玩法闯信创开放社区——用平台宣传企业产品服务 13
如何让你先人一步获得悬赏问题信息?(创作者必看) 12
2024中国信创产业发展大会暨中国信息科技创新与应用博览会 9
中央国家机关政府采购中心:应当将CPU、操作系统符合安全可靠测评要求纳入采购需求 8

添加我为好友,拉您入交流群!

请使用微信扫一扫!