回忆一下我们去饭店点餐,我们坐好,服务员给我们递过来菜单,我们点菜,点完菜我们就可以刷抖音或者玩王者荣耀了。那么过一会儿菜就上来了。谁做的菜? 怎么做的菜?厨师的名字叫啥?他是什么星座的?是不是程序员转行了? 我们一概不关心。
再思考一个场景,我们作为公司的技术部的leader,有需求来了,说是现在我们商城的支付方式太少了,只有银联支付,很多用户反应需要微信支付和支付宝支付。那么你叫来了团队最靠谱的小李,然后跟他说下周希望商城有微信支付的功能,下下周有支付宝支付的功能。小李说没问题,然后你就去忙你自己的事儿了。两周后,支付宝和微信支付功能如期上线,你很开心,并且认为小李很给力。
还有就是战场上,司令员下达命令就是“把我的意大利炮拿出来,把XX山头给我打下来
”。这就是命令,而具体怎么实现,部队里哪些人去做,不是司令员关心的,他只关心XX山头打下来没有。
那么以上的三个例子,都是我们今天要介绍的设计模式的现实写照——命令模式。
命令模式(Command Pattern
)
将“请求”封装成命令对象,以便使用不同的请求、队列或日志来参数化其他对象。命令模式也支持可撤销的操作。
为了加深模式的理解,我们假设要设计一款多功能遥控器,这个遥控器有一排的on
开关和一排的off
开关,我们可以指定某个on/off开关执行某个命令,比如开灯、关灯、打开电视等等。如下图所示:
针对上面说的多功能遥控器,我们来设计对应类图,首先,需要遥控器类RemoteController,在这个类里,包含着一排on按钮(onCommands
)和一排off按钮(offCommands
);其次,创建命令接口Command,提供执行命令的方法execute()
;然后实现具体的指令实现类,如:LightOnCommand和LightOffCommand,当然,具体的操作灯的行为,还是在Light类中,因为这个类才是实际供应商提供给我们关于这盏灯的操作api。具体类图,请见如下所示;
创建命令接口:Command.java
public interface Command {
void execute();
}
创建关灯命令实现类:LightOffCommand.java
public class LightOffCommand implements Command {
private Light light;
public LightOffCommand(Light light) {
this.light = light;
}
public void execute() {
light.off();
}
}
创建开灯命令实现类:LightOnCommand.java
public class LightOnCommand implements Command {
private Light light;
public LightOnCommand(Light light) {
this.light = light;
}
public void execute() {
light.on();
}
}
创建无指令实现类:NoCommand.java
public class NoCommand implements Command {
public void execute() {
System.out.println("Doing nothing!");
}
}
创建供应商所属灯的API类:Light.java
public class Light {
/** 开灯操作 */
public void on() {
System.out.println("Light on!");
}
/** 关灯操作 */
public void off() {
System.out.println("Light off!");
}
}
创建遥控器类:RemoteController.java
public class RemoteController {
private Command[] onCommands;
private Command[] offCommands;
public RemoteController() {
onCommands = new Command[4];
offCommands = new Command[4];
for (int i = 0; i < 4; i++) {
onCommands[i] = new NoCommand();
offCommands[i] = new NoCommand();
}
}
/** 往遥控器中添加命令 */
public void addCommand(int slot, Command onCommand,
Command offCommand) {
onCommands[slot] = onCommand;
offCommands[slot] = offCommand;
}
/** 按遥控器中某个开启键 */
public void pushOnButton(int slot) {
onCommands[slot].execute();
}
/** 按遥控器中某个关闭键 */
public void pushOffButton(int slot) {
offCommands[slot].execute();
}
}
创建测试类:CommandTest.java
public class CommandTest {
public static void main(String[] args) {
Light light = new Light();
RemoteController controller = new RemoteController();
controller.addCommand(0, new LightOnCommand(light),
new LightOffCommand(light));
controller.pushOnButton(0); // 按下遥控器,第一排的ON按钮
controller.pushOffButton(0); // 按下遥控器,第一排的OFF按钮
}
}
输出结果:
Light on!
Light off!
今天的文章内容就这些了:
写作不易,笔者几个小时甚至数天完成的一篇文章,只愿换来您几秒钟的 点赞 & 分享 。
更多技术干货,欢迎大家关注公众号“爪哇缪斯” ~ \(^o^)/ ~ 「干货分享,每天更新」