用命令模式实现这样一个需求:
有个按钮,将一盏电灯的开和关动作都绑定在这个按钮上。另外还有一个undo按钮,可撤消之前的一个动作。
package com.headfirst.chapter6; public interface Command { public void execute(); public void undo(); }
下面这个电灯类,对应上面的图也就是接收者
package com.headfirst.chapter6; public class Light { public void on(){ System.out.println("the light is on"); } public void off(){ System.out.println("the light if off"); } }
下面这个是具体的命令类,也就是开灯命令
package com.headfirst.chapter6; public class LightOnCommand implements Command { private Light light;//有一个接收者实例 public LightOnCommand(Light light) { this.light = light; } public void execute() { light.on(); } public void undo(){ light.off(); } }
package com.headfirst.chapter6; public class LightOffCommand implements Command { private Light light;//有一个接收者实例 public LightOffCommand(Light light){ this.light = light; } public void execute() { light.off(); } public void undo(){ light.on(); } }
下面这个是invoker
package com.headfirst.chapter6; public class SimpleRemoteControl { private Command command; public void setCommand(Command command) { this.command = command; } public void buttonWasPressed(){ command.execute(); } public void undoButtonWasPressed(){ command.undo(); } }
测试类
package com.headfirst.chapter6; public class RemoteControlTest { public static void main(String[] args) { Light light = new Light(); LightOnCommand lightOnCommand = new LightOnCommand(light); LightOffCommand lightOffCommand = new LightOffCommand(light); SimpleRemoteControl simpleRemoteControl = new SimpleRemoteControl(); simpleRemoteControl.setCommand(lightOnCommand); simpleRemoteControl.buttonWasPressed(); simpleRemoteControl.setCommand(lightOffCommand); simpleRemoteControl.buttonWasPressed(); simpleRemoteControl.undoButtonWasPressed();//做一次undo,状态又回到之前 } }
最后打印出:
the light is on
the light if off
the light is on
命令模式的定义:将“请求”封装成对象,以便使用不同的请求,队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。
上面的“队列或日志来参数化”的意思是有很多命令,以队列的方式先后执行。
日志是指将每个操作动作“命令化”,记录在日志中。