前奏:
烤肉摊只有一个老板一个人照顾,人太多,场面混乱,先后等不到保证,烤肉质量也容易下降。大家都盯着烤肉。这其实就是“行为请求者”与“行为实现者”的紧耦合。
若有人退回请求或者要求烤肉重烤,者相当于撤销和重做。所以对请求排队或记录请求日志,以及支持可撤销的操作等行为。
命令模式(Command),将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
命令模式作用:第一,它比较容易地设计一个命令队列;第二,在需要的情况下,可以较容易地将命令记录日志;第三,允许接受请求的一方决定是否要否决请求。
第四,可以容易地实现对请求的撤销和重做;第五,由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。
最关键的优点,就是命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分隔开。
敏捷开发原则告诉我们,不要我代码添加基于猜测的、实际不需要饿功能。如果不清楚一个系统是否需要命令模式,一般就不要着急去实现它,事实上,在需要的时候通过重构实现这个模式并不困难,只有在真正需要如撤销/恢复操作等功能时,把原来的代码重构为命令模式才有意义。
Barbecuer类
package command; /** * 烤肉师傅 * @author 煞笔 * */ public class Barbecuer { public void bakeMutton(){ System.out.println("烤羊肉串"); } public void bakeChickenWing(){ System.out.println("烤鸡翅"); } }
Command类
package command; /** * 命令 * @author 煞笔 * */ public abstract class Command { protected Barbecuer barbecuer; public Command(Barbecuer barbecuer) { super(); this.barbecuer = barbecuer; } public abstract void excuteCommand(); }
BakeMuttonCommand类
package command; /** * 烤羊肉命令 * @author 煞笔 * */ public class BakeMuttonCommand extends Command { public BakeMuttonCommand(Barbecuer barbecuer) { super(barbecuer); } @Override public void excuteCommand() { barbecuer.bakeMutton(); } }
BakeChickenWingCommand类
package command; /** * 烤鸡翅命令 * @author 煞笔 * */ public class BakeChickenWingCommand extends Command { public BakeChickenWingCommand(Barbecuer barbecuer) { super(barbecuer); } @Override public void excuteCommand() { barbecuer.bakeChickenWing(); } }
WaiterGirl类
package command; import java.util.ArrayList; import java.util.List; public class WaiterGirl { protected List<Command> commands = new ArrayList<Command>(); public void setCommand(Command command){ if(command instanceof BakeChickenWingCommand){ System.out.println("没有烤鸡翅了,请点别的"); }else{ commands.add(command); } } public void removeCommand(Command command){ commands.remove(command); } public void notice(){ for(Command c:commands){ c.excuteCommand(); } } }
Business类
package command; public class Business { public static void main(String[] args) { Barbecuer barbecuer = new Barbecuer(); Command command1 = new BakeMuttonCommand(barbecuer); Command command2 = new BakeChickenWingCommand(barbecuer); Command command3 = new BakeMuttonCommand(barbecuer); WaiterGirl girl = new WaiterGirl(); girl.setCommand(command1); girl.setCommand(command2); girl.setCommand(command3); girl.notice(); } }
女服务员记录命令,统一下发命令,命令跟女服务员属于聚合关系,以为女服务员可以记录、下发好多命令。烤肉师傅只管烤肉,接受烤肉命令,烤肉命令要有烤肉师傅执行,烤肉命令和烤肉师傅是聚合关系。