古时候有一天,皇帝大发善心,要大赦天下而且还要减轻赋税,于是大臣们根据皇帝不同的旨意传达不同的指令,不管是什么指令,最终都是由老百姓来执行。这就是命令模式。
一、认识命令模式
1、概念
将客户的请求传入一个对象,请求不同传入的对象也不同。因此可实现二者之间的松耦合,以便适应变化。分离变化与不变的因素。
意思是什么呢?假如皇帝想要大赦天下,那么大臣们就可以根据皇帝的意思,传达大赦天下的指令。皇帝有想要减轻赋税,大臣们可以根据皇帝旨意,传达减轻赋税的指令,皇帝的请求不同,那么大臣们传达的指令也不同。现在应该明白了吧。
2、类图
从上面这张类图我们不难发现,皇帝的最终意思就是要让老百姓去执行,但是自己又不能亲力亲为,于是只把意思跟大臣们一说,大臣们颁布传达具体的指令,最终让老百姓去执行。
这里有五个角色,我们来分析一下:
(1)抽象命令接口Command(圣旨):声明执行的方法。
(2)具体命令对象ConcreteCommand(具体圣旨):具体的命令。
(3)接受者对象Receiver(老百姓):接受者对象,真正执行命令的对象。
(4)传递命令对象Invoker(大臣):持有命令对象,要求Receiver执行请求。
(5)客户端对象Client(皇帝):创建具体命令,设置命令对象的接受者。
3、命令模式与代理模式的区别
这个模式乍一看有点像代理模式,怎么看都是大臣是一个代理,其实不是,在这里我们提前说明一下,免得你稀里糊涂看完了一头雾水,下面进行一个对比分析。
(1)在代理(委托)模式中,调用者就是委托者,执行者就是被委托者,委托者和被委托者接口定义是相同的。命令模式不同,调用者不关注执行者的接口定义是否和它一致。
我们还是拿皇帝与大臣的关系举例子,代理模式中,要求皇帝和大臣们接口定义一样,也就是执行一样的操作。但是命令模式不同,皇帝和大臣的接口定义可以不一致,皇帝可以有自己其他的想法。
(2)在调用时机上,代理模式的具体执行是只能在特定的调用者内部执行(接口相同);命令模式的具体执行可以在任何调用者内部执行(接口不相同也可以)。
意思是什么呢?在代理模式中大臣们只执行一个皇帝(同一个人,谁当皇帝都只听朱元璋的)的命令,命令模式不一样,大臣们可以执行好几个皇帝的命令,也就是说不管谁当皇帝,都只听在任皇帝的。
现在你能分清了吧,那我们就具体来看一下命令模式如何实现的。
二、代码实现命令模式
第一步:创建接受者(老百姓)
第二步:抽象命令接口Command(圣旨)
第三步:具体命令对象ConcreteCommand(具体圣旨)
首先是大赦天下
然后是减轻赋税
第四步:传递命令对象Invoker(大臣)
第五步:客户端对象Client(皇帝)模拟整个过程
三、分析命令模式
1、使用场景
命令模式适用于“请求-响应”模式的功能,把用户的请求封装成具体的命令对象,用户请求什么,我们就调用什么命令,用户无需知道命令执行逻辑是什么。
2、优缺点
优点:将用户的请求和请求的实现实现解耦,用户有了新需求,只需要增加一个需求实现对象即可。
缺点:请求比较多的时候,会使得整个类变得庞大。
OK,这就是命令模式,如有问题还请批评指正。