命令模式
说实话,不太想套用学术性的解释去写一个随记
这个模式,我们从语义上来拆解
命令:A叫B干什么
那么看起来A和B的关系是十分紧密的,很可能是本身A会持有B这个对象,并且联系紧密的
那就有问题咯,在OO原则中这是一个紧耦合的关系
那么我们得来解决这个问题,也就是所谓的解耦
还记得冒泡算法中,用第三个变量来交换a和b数值的位置吗
if (a > b) { c = a; a = b; b = c;}
是的,我们一样在A和B中间放一个桥梁C(它可不是第三者)
那么作为一个桥梁的职责是什么呢(根据单一职责的设计原则,我们只强调桥梁的责任在于沟通)
C需要了解A的请求和B的能力
A和B是一个典型的请求者和执行者的关系
也就是说A有一个诉求,而C要进行诉求传递,并且传递的诉求必须是B所能理解的
这就像是这样的:
我们先用实际的场景来匹配一下吧
小明到了餐厅,向服务员点了一份套餐:蒜香排骨套餐,服务员将订单给了厨师,叫了一句:订单来了!然后厨师就开始做菜了。做好后,小明的餐桌上多了一份套餐。
首先这里的小明是Client,他从服务员(Invoker)中得知可以通过订单(RealCommand)来进行点单,服务员得到订单后在合适的时候调用execute,这样厨师(Receiver)就知道要要做菜(action)了。
那么我们来实际看一下这个场景中,小明虽然创建了订单,但他并不能直接和厨师交流,而服务员虽然传递了订单,但他也仅仅比小明多了一个权限:就是喊一声“订单来了”。这样的好处就是消费者无法直接干扰到生产者的行为,这在使得生产者专注于生产是很有帮助的行为。
也就是说,它确实达到了我们的设计目的:解耦。
松散掉请求者和执行者的关系,这从小明和厨师的关系可以看得出来
可以想象一下,像是古时候天子诏书,那时候交通不便,地域广阔
我们想想也知道皇帝不会太清楚地方官的情况,但通过一纸文书,就是一个命令,中间自有刺史神马的来传递
地方官接收到诏书之后,反正按着来做就好了
差不多也就是这种关系了
并且这一纸文书,它可以不仅仅是一个命令,这也是常说的命令模式可以方便的支持撤销的动作
试想,实际执行者的对象是命令对象的私有变量,也就是说命令对象是可以拥有全部 实际执行者对象能力的
public class Command { private Receiver receiver; public void execute() { receiver.do(); } public void undo() { receiver.nodo(); }}
自然可以方便地增加一个撤销命令的方法
最后再来回顾下命令模式做的事:
我们把算法封装到一个命令对象中,对外开放一个执行的接口,方便任务队列(线程)的调用,也就是说任务队列并不需要知道这个命令的详情,只需要知道并调用开放的执行接口即可