命令模式,将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求
日志,以及支持可撤销的操作。 ——摘自《大话设计模式》
Ps:“将请求封装为对象”的思想即是该种设计模式的精华。
基本结构如下:
①、Receiver,命令的接收者,也是命令的实际执行者
具体方法一
具体方法二
……
②、Command,命令超类
Receiver 的引用
execute() 命令的执行方法,子类覆写该方法
③、ConcreteCommand,具体的命令,继承Command
concreteExcute() 覆写超类的 execute() 方法
根据实际情况调用 Receiver 的某个具体方法,覆写之前会为 Receiver 的引用赋值
④、Invoker,请求者,提供给外界用于命令的下达、取消、记录、组合等
Command 的引用
setCommand() 下达命令的方法
cancelCommand() 取消命令的方法
notifyExcute() 通知命令执行的方法
示例代码: 以顾客点烧烤为例
①、Receiver #########################################
/**
* 烤肉串者,Receiver(命令的接受者,也是最终执行命令的角色)
*/
public class Barbecuer {
//烤羊肉
public void bakeMutton(){
System.out.println("烤羊肉开始……");
}
//烤鸡翅
public void bakeChickenWing(){
System.out.println("烤鸡翅开始……");
}
}
②、Command #########################################
/**
* 命令的超类,该模式的核心
*/
public abstract class Command {
protected Barbecuer receiver; //命令的接收者
public Command(Barbecuer receiver){
this.receiver = receiver;
}
public abstract void excuteCommand();
}
③、ConcreteCommand #########################################
/**
* 烤羊肉命令,具体命令一
*/
public class BakeMuttonCommand extends Command {
public BakeMuttonCommand(Barbecuer receiver) {
super(receiver);
}
@Override
public void excuteCommand() { //覆写命令执行,调用receiver的烤羊肉方法
this.receiver.bakeMutton();
}
@Override
public String toString() { //覆写toString方法,便于记录
return "羊肉一串";
}
}
/**
* 烤鸡翅命令,具体命令二
*/
public class BakeChickenWing extends Command {
public BakeChickenWing(Barbecuer receiver) {
super(receiver);
}
@Override
public void excuteCommand() { //覆写命令执行,调用receiver的烤鸡翅方法
this.receiver.bakeChickenWing();
}
@Override
public String toString() { //覆写toString方法,便于记录
return "鸡翅一串";
}
}
④、Invoker #########################################
/**
* 服务员,记录、撤销命令并通知执行
*/
public class Waiter {
private List<Command> commandList = new ArrayList<Command>(); //命令集合
//添加订单
public void setCommand(Command command){
commandList.add(command);
System.out.println("添加订单:"+command.toString()+","+new Date());
}
//取消订单
public void cancelCommand(Command command){
commandList.remove(command);
System.out.println("取消订单:"+command.toString()+","+new Date());
}
//通知命令执行
public void notifyExcute(){
for(Command command:commandList){
command.excuteCommand();
}
}
}
测试方法:
public class Test {
public static void main(String[] args) throws Exception {
Barbecuer duke = new Barbecuer(); //厨师duke
Command command1 = new BakeMuttonCommand(duke); //烤羊肉命令,指定厨师
Command command2 = new BakeChickenWing(duke); //烤鸡翅命令,指定厨师
Waiter ming = new Waiter(); //服务员小明
ming.setCommand(command1); //记录命令一
ming.setCommand(command2); //记录命令二
ming.cancelCommand(command2); //取消命令二
ming.notifyExcute(); //下单结束,通知厨师开始烧烤
}
}
测试结果:
添加订单:羊肉一串,Fri Oct 18 09:33:21 CST 2013
添加订单:鸡翅一串,Fri Oct 18 09:33:21 CST 2013
取消订单:鸡翅一串,Fri Oct 18 09:33:21 CST 2013
烤羊肉开始……