《设计模式之禅》之命令模式
一、命令模式定义
将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或记录请求日志,可以提供命令的撤销和恢复功能。
命令模式的通用类图(这里我抽象为如下):
1.Receive接收者角色
该角色就是干活的角色,命令传递到这里是应该被执行的。
2.Command命令角色
需要执行的所有命令都在这里声明。
3.Invoker调用者角色
接收到命令,并执行命令。
二、命令模式的应用
1.命令模式的优点
a.类间解耦
调用者角色与接受者角色之间没有任何依赖关系,调用者实现功能时只需调用Command抽象类的execute方法就可以,不需要了解到底是哪个接收者执行。
b.可扩展性
Command的子类可以非常容易地扩展,而调用者Invoker和高层次的模式Client不产生严重的代码耦合。
c.命令模式结合其他模式会更优秀
命令模式可以结合责任链模式,实现命令族解析任务;结合模板方法模式,则可以减少Command子类的膨胀问题。
2.命令模式的缺点
命令模式也有其缺点的,请看Command的子类:如果有N个命令,问题就出来了,Command的子类就可不是几个,而是N个,这个类膨胀得非常大,这个就需要读者在项目中慎重考虑使用。
3.命令模式的使用场景
只要你认为是命令的地方就可以采用命令模式,例如GUI开发中,一个按钮的点击是一个命令,可以采用命令模式;模拟DOS命令的时候也是要采用命令模式;触发-反馈机制的处理也亦如此。
三、最佳实践
每一个模式到实际应用的时候都会有一些变形,命令模式的Receiver在实际应用中一般都会被封装掉(除非非常必要,例如撤销处理),那是因为在项目中:约定的优先级最高,每一个命令是对一个或多个的Receiver的封装,我们可以在项目中通过有意义的类名或命令名处理命令角色和接收者角色的耦合关系(这就是约定),减少高层模块(Client类)对低层模块(Receiver角色类)的依赖关系,提高系统整体的稳定性。因此,建议大家在实际的项目开发时采用封闭Receiver的方式,减少Client对Reciver的依赖,该方案只是对Command抽象类及其子类有一定的修改。
代码地址:https://github.com/developers-youcong/DesignPatternPractice/tree/master/Command