首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

设计模式篇——命令模式

项目经理的重要性

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

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

类图很简单,一个抽象组类,三个具体组继承自抽象组,客户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://kuaibao.qq.com/s/20200507A0POXZ00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码

添加站长 进交流群

领取专属 10元无门槛券

私享最新 技术干货

扫码加入开发者社群
领券