命令模式可将“动作的请求者”从“动作的执行者”对象中解耦。
classDiagram
class Command
<<interface>> Command
Command:excute()
class Invoker
Invoker:setCommand()
class ConcreteCommand
ConcreteCommand:execute()
Invoker o-- Command
Command <|.. ConcreteCommand
class Reciver
Reciver:action()
ConcreteCommand --> Reciver
命令模式
reciver是一个动作的执行者,大白话就是这是个负责执行动作的对象,他知道自己要做什么,比如电灯的开灯对象知道自己的动作就是开灯。
ConcreteCommand对象则封装了该reciver对象,他不关心reciver对象到底能做什么,他只想知道reciver对象能够执行的动作如何实现Command接口,也就是excute方法。
来到调用者Invoker这一块,调用者是一个拥有setCommand方法的对象,也就是说他能够将实现Command接口的对象放到他的变量中,这里并没有指出如何存储这些成员变量。
调用者可以调用自己本身包含的命令对象,并且执行excute方法。而这些命令对象到底做什么只有调用者在调用setCommand方法的时候知道。
打个比方,如果我们有一个遥控器对象,遥控器上拥有很多插槽,并且该遥控器能控制不同的电器,而电器的行为又各不相同。所以我们可以通过这个模式,将电器的行为action封装成命令对象ConcreteCommand,最后通过遥控器将这些命令对象设置到遥控器的插槽上。而遥控器上的插槽必须先规定好如何放置这些电器的开关。
因为客户端只拿到了一个包含命令对象的调用者对象。执行的时候也不知道调用者对象包含的每个命令对象都包含了什么。所以使用该模式的人应该自己定义调用者应该根据什么规则来setCommand。
但是话又说回来,其实这个调用者完全可以不知道这些插槽到底包含了什么开关,而只需要将这些插槽上的命令对象交给reciver直接执行。