命令模式(Command):将一个请求封装成一个对象,从而可以使用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作。
命令模式结构图如下:
接下来我们看看命令模式的Java代码实现
命令抽象类
1 //Command类,用来声明执行操作的接口,其实就是命令的抽象类 2 abstract class Command{ 3 protected Receiver receiver; 4 public Command(Receiver receiver){ 5 this.receiver = receiver; 6 } 7 8 abstract public void Execute(); 9 }
命令的具体类
1 //具体的命令类 2 class ConcreteCommand extends Command{ 3 public ConcreteCommand(Receiver receiver) { 4 super(receiver); 5 } 6 7 @Override 8 public void Execute() { 9 receiver.Action(); 10 11 } 12 13 }
请求的收集发布者
//Invoker类,接受请求,发布命令 class Invoker{ private Command command; public void setCommand(Command command){ this.command = command; } public void ExecuteCommand() { command.Execute(); } }
命令的执行者
//Receiver类,执行请求的类 class Receiver{ public void Action(){ System.out.println("执行请求!"); } }
客户端代码
1 /** 2 * 命令模式 3 * @author yiRain 4 * 5 */ 6 public class CommandTest { 7 8 public static void main(String[] args) { 9 Receiver receiver = new Receiver(); 10 Command command = new ConcreteCommand(receiver); 11 Invoker invoker = new Invoker(); 12 13 invoker.setCommand(command); 14 invoker.ExecuteCommand(); 15 } 16 17 }
执行结果
到这里基本算介绍完了命令模式,下面举个例子来帮助理解。
去公司的路上有一家烧烤店,接下来我们来模拟一下顾客来烧烤店吃烧烤的情况
首先要有服务员,服务员记录顾客的点单(烤鸡翅,烤羊肉串),并送到后厨,如果什么材料没了,还要及时反馈给顾客
接着要有厨师,厨师的工作就是烤鸡翅,烤羊肉串等等。
代码实现:
1 package designPattern; 2 3 import java.awt.List; 4 import java.util.ArrayList; 5 import java.util.Date; 6 7 8 /** 9 * 烧烤店模拟命令模式 10 * @author yiRain 11 * 12 */ 13 public class BarbecueTest { 14 public static void main(String[] args) { 15 //开店前的准备 16 Barbecuer boy = new Barbecuer();//厨师 17 //准备好菜单 18 CommandEx c1 = new ConcreteChickenWings(boy); 19 CommandEx c2 = new ConcreteShishKebab(boy); 20 CommandEx c3 = new ConcreteShishKebab(boy); 21 //服务员 22 waiter girl = new waiter(); 23 24 //开门营业 25 girl.setOrder(c1); 26 girl.setOrder(c2); 27 girl.setOrder(c3); 28 29 //点完了,通知后厨 30 girl.Notify(); 31 } 32 } 33 34 //烤鸡翅抽象类 35 abstract class CommandEx{ 36 protected Barbecuer barbecuer; 37 public CommandEx(Barbecuer barbecuer){ 38 this.barbecuer = barbecuer; 39 } 40 41 abstract public void Execute(); 42 } 43 44 //烤鸡翅具体类 45 class ConcreteChickenWings extends CommandEx{ 46 47 public ConcreteChickenWings(Barbecuer barbecuer) { 48 super(barbecuer); 49 } 50 51 @Override 52 public void Execute() { 53 barbecuer.doChickenWings(); 54 } 55 } 56 //烤羊肉串具体类 57 class ConcreteShishKebab extends CommandEx{ 58 59 public ConcreteShishKebab(Barbecuer barbecuer) { 60 super(barbecuer); 61 } 62 63 @Override 64 public void Execute() { 65 barbecuer.doShishKebab(); 66 } 67 68 } 69 //服务员 70 class waiter{ 71 ArrayList<CommandEx> orders = new ArrayList<CommandEx>(); 72 //设置订单 73 public void setOrder(CommandEx commandEx){ 74 if((commandEx.toString()).contains("designPattern.ConcreteChickenWings")){ 75 System.out.println("鸡翅没啦,点别的吧!"); 76 }else{ 77 orders.add(commandEx); 78 if(commandEx.toString().contains("designPattern.ConcreteShishKebab")){ 79 System.out.println("增加订单:"+"烤羊肉串"); 80 } 81 } 82 } 83 84 //取消订单 85 public void cancelOrder(CommandEx commandEx){ 86 orders.remove(commandEx); 87 System.out.println("取消订单"+commandEx.toString()); 88 } 89 90 //通知全部执行 91 public void Notify(){ 92 for(int i=0;i<orders.size();i++){ 93 orders.get(i).Execute(); 94 } 95 } 96 97 } 98 99 //厨师 100 class Barbecuer{ 101 public void doShishKebab(){ 102 System.out.println("烤羊肉串"); 103 } 104 public void doChickenWings(){ 105 System.out.println("烤鸡翅"); 106 } 107 }
运行结果: