标签:
行为型:Command(命令模式)
命令模式:
目的:其实一般设计模式就是为了解耦。也没什么特别的,命令模式实际上就是将命令的请求者和命令的执行者解耦。
白话:领导说了,让把这个月的项目计划压缩到三个礼拜完成,还说了:"不管你用什么办法"。这句“不管你用什么办法”就是我们所说的解耦。我不需要关心你怎么去做,我只要你能实现我想达到的目的。
模式结构:一般包含下面几个部分。
Client:客户
Invoker:命令触发者
Command:命令
ConcreteCommand:具体命令实现
Receiver:命令执行者(接收者)
还是按生活场景来做比喻,现在我们(Client)来到了一家餐厅,服务员(Invoker)帮我们下了一个订单(ConcreteCommand),交给了厨师(Receiver)。用订单来传递信息的话,服务员和厨师都不需要互相了解和沟通。
这是Head First设计模式中的举例,其实生活中还有很多的场景会用到命令模式。但我想,没有什么会比领导跟你说不管你用什么办法,必须在这个星期内完成任务,这样的情况更让你感到深刻了。
下面我们用一个电视遥控器的Demo来演示:
package top.gabin.oa.web.design.command; /** * 命令接口 * @author linjiabin on 16/5/2 */ public interface Command { /** * 执行命令 */ void execute(); /** * 撤销命令 */ void undo(); }
package top.gabin.oa.web.design.command; /** * 电视接口 * @author linjiabin on 16/5/2 */ public interface TV { void powerOn(); void powerOff(); }
package top.gabin.oa.web.design.command; /** * 电源开关 * @author linjiabin on 16/5/2 */ public class PowerCommand implements Command{ private TV tv; public PowerCommand(TV tv) { this.tv = tv; } @Override public void execute() { tv.powerOn(); } @Override public void undo() { tv.powerOff(); } }
package top.gabin.oa.web.design.command; /** * 乐视TV * @author linjiabin on 16/5/2 */ public class LeshiTv implements TV { @Override public void powerOn() { System.out.println("打开电视"); } @Override public void powerOff() { System.out.println("关掉电视"); } }
package top.gabin.oa.web.design.command; /** * 遥控器 * @author linjiabin on 16/5/2 */ public class RemoteControl { // 最简单的单例模式 private static TV tv = new LeshiTv(); public void powerButtonOn() { PowerCommand powerCommand = new PowerCommand(tv); powerCommand.execute(); } public void powerButtonOff() { PowerCommand powerCommand = new PowerCommand(tv); powerCommand.undo(); } }
/** * 命令测试类 * @author linjiabin on 16/5/2 */ public class TestCommand { @Test public void testCommand() { RemoteControl remoteControl = new RemoteControl(); remoteControl.powerButtonOn(); remoteControl.powerButtonOff(); } }
输出:
打开电视
关掉电视
上述的Demo,主要是分离了电视厂商的功能实现和遥控器按钮点击对应的命令。就如同我们匹配了电视和遥控器,这时候遥控器持有一个电视厂商的实现,在我们点击任意遥控器按钮的同时,遥控器会将持有的电视厂商传递给命令对象,而由命令对象去操作实际电视厂商的接口。
好处很明显,电视厂商不需要再关注遥控器的按钮是如何分布的,按下之后该执行什么操作。反正电视厂商只提供具体功能的接口,遥控器只管生成对应的命令,并将实际命令的执行者:电视厂商传递进去即可。
这看上去似乎没什么了不起的?但你别忘了,你随时都会适配一个新的电视厂商的实现,你确定你想要让所有的遥控器按钮都绑定到一个厂商实现吗?
不知道此时的你是否会有一种感触:哦天,要是我的老板也懂得命令模式,我是不是再也不用跟他解释我昨天是如何搞定客户的(那一些细到我请了客户吃过几次饭,都点什么菜的细节?)
标签:
原文地址:http://www.cnblogs.com/gabin/p/5453410.html