模式说明

请求某个命令执行者执行命令时,最直接的方式是客户端直接传入命令给执行者,但这样就无法管理命令(或者说只能由客户端来管理),加重了客户端的负担。此类场景可以将命令封装成类,其内持有命令执行者实例,另有一个execute方法,该方法调用命令执行者实例的执行方法。再引入一个命令请求者(或称命令传递者,命令管理者)类来持有命令集合实例,其内有追加命令方法,删除命令方法,最重要的是有一个传递命令的方法request,该方法通过调用其持有的命令对象的execute方法来实现请求(execute内部调用了命令执行者自身的执行方法)。

本示例展示点菜场景下,命令请求者服务员(Waiter类)如何管理命令(Order类),并通过request调用Order内的excute方法,让厨师(Chef类)执行做菜方法。

结构

抽象命令类:
持有一个命令执行者Chef类,并通过带参构造方法初始化Chef属性。有一个抽象方法execute
具体命令类
继承抽象命令类,实现execute方法,内部调用Chef的做菜方法。
命令执行类
执行命令的角色Chef,内有做菜方法(本例中的makeMuttonmakeChickenWings)。
命令请求者类
管理命令和请求执行者执行命令的角色,类内以List持有多个命令实例。维护追加命令方法addOrder,撤销命令方法cancelOrder和请求方法requestrequest内遍历Order并调用其execute方法。

代码演示

  1. package com.yukiyama.pattern.behavior;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. /**
  5. * 命令模式
  6. */
  7. public class CommandDemo {
  8. public static void main(String[] args) {
  9. // 声明命令执行者
  10. Chef chef = new Chef();
  11. // 声明具体命令,通过构造器传入该命令对应的执行者(本例只有一个执行者)
  12. Order muttonOrder = new MuttonOrder(chef);
  13. Order wingsOrder = new ChickenWingsOrder(chef);
  14. // 声明命令请求者
  15. Waiter waiter = new Waiter();
  16. // 将命令传入请求者内
  17. waiter.addOrder(muttonOrder);
  18. waiter.addOrder(wingsOrder);
  19. // 命令请求者执行request方法,输出"烤羊肉串",“烤鸡翅”
  20. waiter.request();
  21. }
  22. }
  23. /**
  24. * 抽象命令类
  25. * 持有命令执行者类Chef,通过有参构造器传入Chef来初始化。有一个execute抽象方法。
  26. */
  27. abstract class Order{
  28. protected Chef chef;
  29. public Order(Chef chef){
  30. this.chef = chef;
  31. }
  32. public abstract void execute();
  33. }
  34. /**
  35. * 具体命令类
  36. * 实现抽象命令类,实现execute方法,方法内部调用其持有的Chef的做菜方法。
  37. * 下例是点羊肉串的命令MuttonOrder,execute方法内调用Chef的做羊肉串方法
  38. * makeMutton。
  39. */
  40. class MuttonOrder extends Order{
  41. public MuttonOrder(Chef chef) {
  42. super(chef);
  43. }
  44. @Override
  45. public void execute() {
  46. chef.makeMutton();
  47. }
  48. }
  49. /**
  50. * 具体命令类
  51. * 下例是点鸡翅的命令ChickenWingsOrder,execute方法内调用Chef的做鸡翅
  52. * 方法makeChickenWings。
  53. */
  54. class ChickenWingsOrder extends Order{
  55. public ChickenWingsOrder(Chef chef) {
  56. super(chef);
  57. }
  58. public void execute() {
  59. chef.makeChickenWings();
  60. }
  61. }
  62. /**
  63. * 命令请求者类
  64. * 持有一个命令实例集合List<Order>。维护管理命令的方法addOrder,cancel,
  65. * request。其中传递命令的请求方法request遍历该类持有的命令集合,并执行命令
  66. * 类的execute方法。
  67. */
  68. class Waiter{
  69. private List<Order> orders = new ArrayList<>();
  70. public void addOrder(Order order) {
  71. orders.add(order);
  72. }
  73. public void cancelOrder(Order order) {
  74. orders.remove(order);
  75. }
  76. public void request() {
  77. for(Order order : orders) {
  78. order.execute();
  79. }
  80. }
  81. }
  82. /**
  83. * 命令执行者类
  84. * 真正执行命令的角色,维护做菜方法。
  85. * 下例是烤羊肉串MakeMutton和烤鸡翅MakeChickenWings方法。
  86. */
  87. class Chef{
  88. public void makeMutton() {
  89. System.out.println("烤羊肉串");
  90. }
  91. public void makeChickenWings() {
  92. System.out.println("烤鸡翅");
  93. }
  94. }