命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。
Command类,抽象命令类。ConcreteCommand具体命令类。
Receiver,接受者类,用于执行一个请求操作。
Invoker类,要求该命令执行这个请求。
命令类
//抽象命令类
abstract class Command {// 命令的接受者protected Receiver receiver;public Command(Receiver receiver){this.receiver = receiver;}//执行命令public abstract void excuteCommand();
}//具体命令类
class ConcreteCommand extends Command{public ConcreteCommand(Receiver receiver){super(receiver);}public void excuteCommand(){receiver.action();}
}
Receiver
class Receiver{public void action(){System.out.println("执行请求!");}
}
Invoker
class Invoker{private Command command;public void setCommand(Command command){this.command = command;}public void executeCommand(){command.excuteCommand();}
}
客户端
public class Test {public static void main(String[] args) {System.out.println("**********************************************"); System.out.println("《大话设计模式》代码样例");System.out.println(); Receiver receiver = new Receiver();Command command = new ConcreteCommand(receiver);Invoker invoker = new Invoker();invoker.setCommand(command);invoker.executeCommand();System.out.println();System.out.println("**********************************************");}
}
饭店点餐。
服务员负责记录点餐,通知厨师。厨师负责做(执行)。命令就是点的餐。
命令类
//抽象命令类
abstract class Command {protected Barbecuer receiver;public Command(Barbecuer receiver){this.receiver = receiver;}//执行命令public abstract void excuteCommand();
}
//烤羊肉命令类
class BakeMuttonCommand extends Command{public BakeMuttonCommand(Barbecuer receiver){super(receiver);}public void excuteCommand(){receiver.bakeMutton();}
}//烤鸡翅命令类
class BakeChickenWingCommand extends Command{public BakeChickenWingCommand(Barbecuer receiver){super(receiver);}public void excuteCommand(){receiver.bakeChickenWing();}
}
Barbecuer类(请求的接受者)
//烤肉串者
class Barbecuer{//烤羊肉public void bakeMutton(){System.out.println("烤羊肉串!");}//烤鸡翅public void bakeChickenWing(){System.out.println("烤鸡翅!");}
}
服务员类
class Waiter{private ArrayList orders = new ArrayList();//设置订单public void setOrder(Command command){String className=command.getClass().getSimpleName();if (className.equals("BakeChickenWingCommand")){System.out.println("服务员:鸡翅没有了,请点别的烧烤。");}else{this.orders.add(command);System.out.println("增加订单:"+className+" 时间:"+getNowTime());}}//取消订单public void cancelOrder(Command command){String className=command.getClass().getSimpleName();orders.remove(command);System.out.println("取消订单:"+className+" 时间:"+getNowTime());}//通知执行public void notifyCommand(){for(Command command : orders){command.excuteCommand();}}private String getNowTime(){SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");return formatter.format(new Date()).toString();}
}
客户端
public class Test {public static void main(String[] args) {System.out.println("**********************************************"); System.out.println("《大话设计模式》代码样例");System.out.println(); // 开店前的准备Barbecuer boy = new Barbecuer();// 烤肉厨师Command bakeMuttonCommand1 = new BakeMuttonCommand(boy); // 烤羊肉串Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy); // 烤鸡翅Waiter girl = new Waiter(); // 服务员System.out.println("开门营业,顾客点菜");girl.setOrder(bakeMuttonCommand1); // 下单烤羊肉串girl.setOrder(bakeMuttonCommand1); // 下单烤羊肉串girl.setOrder(bakeMuttonCommand1); // 下单烤羊肉串girl.setOrder(bakeMuttonCommand1); // 下单烤羊肉串girl.setOrder(bakeMuttonCommand1); // 下单烤羊肉串girl.cancelOrder(bakeMuttonCommand1); // 取消一串羊肉串订单girl.setOrder(bakeChickenWingCommand1); // 下单烤鸡翅System.out.println("点菜完毕,通知厨房烧菜");girl.notifyCommand(); // 通知厨师System.out.println();System.out.println("**********************************************");}
}
命令模式的优点
敏捷开发原则:不要为代码添加基于猜测的 ,实际不需要的功能。
如果不清楚一个系统是否需要命令模式,一般不要着急实现它,事实上,在需要的时候通过重构实现这个模式并不困难,只有在真正需要如撤销/恢复操作等功能时,把原来的代码重构为命令模式才有意义。