命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式。请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
1.抽象出待执行的动作以参数化某对象。 2.在不同的时刻指定、排列和执行请求。 3.支持取消操作 4.支持修改日志,这样当系统崩溃时,这样修改可以被重做一遍。 5.用构建在原语操作上的高层操作构造一个系统。
命令模式(Command)的应用效果: 1)command模式将调用操作的对象和实现该操作的对象解耦 2)可以将多个命令装配成一个复合命令,复合命令是Composite模式的一个实例 3)增加新的command很容易,无需改变已有的类
1.接收者Receriver :是一个类的实例,负责执行与请求相关的具体操作 2.命令接口Command:封装请求的若干个方法 3.具体命令ConcreteCommand: 实现命令接口的实例 4.请求者Invoker:是一个包含Command接口变量的类的实例。请求者负责调用具体命令,让具体命令执行哪些封装了请求的方法
1.定义接收者Receiver:知道如何实现与执行一个请求相关的操作
package com.jdbc.receiver; /** * @ClassName: CellingFan * @Description:接收者 * @author: lsh * @date: 2019年5月21日 */ public class CellingFan { public static final int HIGH = 3; public static final int MEDIUM = 2; public static final int LOW = 1; public static final int OFF = 0; int speed; // 记录风扇的状态 public CellingFan() { speed = OFF; } public void high() { speed = HIGH; System.out.println("风扇速度:高"); } public void medium() { speed = MEDIUM; System.out.println("风扇速度:中"); } public void low() { speed = LOW; System.out.println("风扇速度:低"); } public void off() { speed = OFF; System.out.println("风扇速度:停"); } public int getSpeed() { return speed; } }2.定义Command,声明执行操作的接口
package com.jdbc; /** * @ClassName: Command * @Description:命令接口 * @author: lsh * @date: 2019年5月21日 */ public interface Command { public void execute(); public void undo(); }3.定义具体的命令ConcreteCommand,将一个接收者对象绑定于一个动作
package com.jdbc.concretecommand; import com.jdbc.Command; import com.jdbc.receiver.CellingFan; /** * @ClassName: CellingFanOffCommand * @Description:具体命令1 ConcreteCommand:实现命令接口类的实例 * @author: lsh * @date: 2019年5月21日 */ public class CellingFanHighCommand implements Command { // 持有接收者的应用,将一个接收对象绑定于一个动作 CellingFan cellingFan; int preSpeed; // 记录之前的速度 public CellingFanHighCommand(CellingFan cellingFan) { this.cellingFan = cellingFan; } @Override public void execute() { preSpeed = cellingFan.getSpeed(); cellingFan.high(); } @Override public void undo() { if (preSpeed == CellingFan.HIGH) { cellingFan.high(); }else if (preSpeed == CellingFan.MEDIUM) { cellingFan.medium(); }else if (preSpeed == CellingFan.LOW) { cellingFan.low(); }else if (preSpeed == CellingFan.OFF) { cellingFan.off(); } } } package com.jdbc.concretecommand; import com.jdbc.Command; import com.jdbc.receiver.CellingFan; /** * @ClassName: CellingFanOffCommand * @Description:具体命令2 ConcreteCommand:实现命令接口类的实例 * @author: lsh * @date: 2019年5月21日 */ public class CellingFanOffCommand implements Command { // 持有接收者的应用,将一个接收对象绑定于一个动作 CellingFan cellingFan; int preSpeed; // 记录之前的速度 public CellingFanOffCommand(CellingFan cellingFan) { this.cellingFan = cellingFan; } @Override public void execute() { preSpeed = cellingFan.getSpeed(); cellingFan.off(); } @Override public void undo() { if (preSpeed == CellingFan.HIGH) { cellingFan.high(); }else if (preSpeed == CellingFan.MEDIUM) { cellingFan.medium(); }else if (preSpeed == CellingFan.LOW) { cellingFan.low(); }else if (preSpeed == CellingFan.OFF) { cellingFan.off(); } } }4.定义Invoker,要求该命令执行这个请求。
package com.jdbc.Invoker; import com.jdbc.Command; import com.jdbc.concretecommand.NoCommand; /** * @ClassName: RemoteControl * @Description:请求者 * @author: lsh * @date: 2019年5月21日 */ public class RemoteControl { Command command; public void setCommand(Command command) { this.command = command; } public void buttonWasPushed() { command.execute(); } public void undoButtonWasPushed() { command.undo(); } }5.测试:
package com.jdbc.client; import com.jdbc.Invoker.RemoteControl; import com.jdbc.concretecommand.CellingFanHighCommand; import com.jdbc.concretecommand.CellingFanOffCommand; import com.jdbc.receiver.CellingFan; /** * @ClassName: RemoteLoader * @Description:TODO * @author: lsh * @date: 2019年5月22日 */ public class RemoteLoader { public static void main(String[] args) { // 创建命令的接收者 CellingFan cellingFan = new CellingFan(); // 创建命令对象,并设定接受者 Command cellingFanOffCommand = new CellingFanOffCommand(cellingFan); Command cellingFanHighCommand = new CellingFanHighCommand(cellingFan); // 创建命令执行者 RemoteControl rc = new RemoteControl(); rc.setCommand(cellingFanHighCommand); rc.buttonWasPushed(); rc.setCommand(cellingFanOffCommand); rc.buttonWasPushed(); rc.undoButtonWasPushed(); } }测试结果如下: