设计模式(18/23) - 命令模式

23 阅读3分钟

命令模式

1 概述

  • 命令模式(Command Pattern)是一种行为型设计模式,它将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化,对请求排队或记录请求日志,以及支持可撤销的操作。命令模式通过将请求的发送者和接收者解耦,使得请求的发送和处理具有更高的灵活性和扩展性。

2 优缺点及应用场景

2.1 优点

  • 1)解耦请求的发送者和接收者:发送者和接收者之间没有直接依赖,降低了系统的耦合度。
  • 2)可扩展性强:新的命令可以很容易地添加到系统中,符合开闭原则。
  • 3)支持撤销和重做:通过在命令对象中实现undo方法,可以支持撤销和重做操作。
  • 4)支持宏命令:可以将多个命令组合成一个宏命令,实现更复杂的操作。

2.2 缺点

  • 1)增加类的数量:每一个具体命令都需要一个类,会导致类的数量增多。
  • 2)增加系统的复杂性:需要额外的代码来实现命令的封装和处理,增加了系统的复杂性。

2.3 应用场景

  • 1)操作需要撤销和重做:需要支持操作的撤销和重做功能的场景。
  • 2)请求的发送者和接收者需要解耦:发送者和接收者之间需要独立变化的场景。
  • 3)支持宏命令:需要将多个操作组合成一个宏操作的场景。

3 结构

  • 1)命令(Command):定义命令接口,声明执行操作的方法。
  • 2)具体命令(ConcreteCommand):实现命令接口,封装具体操作和接收者。
  • 3)接收者(Receiver):负责执行具体的操作。
  • 4)调用者(Invoker):持有命令对象,并通过命令对象执行请求。
  • 5)客户端(Client):创建具体命令对象并设置其接收者。

4 实现

4.1 UML 类图

命令模式.jpg

4.2 代码示例

// 创建一个命令接口
interface Order {
  void execute();
}

// 创建一个请求类
class Stock {
  private String name = "ABC";
  private int quantity = 10;

  public void buy() {
    System.out.println("Stock [ Name: " + name + ", Quantity:" + quantity + " ]bought ");
  }

  public void sell() {
    System.out.println("Stock [ Name: " + name + ", Quantity:" + quantity + " ]sold ");
  }
}

// 创建实现了 Order 接口的实体类:买入股票
class BuyStock implements Order {
  private Stock abcStock;

  public BuyStock(Stock abcStock) {
    this.abcStock = abcStock;
  }

  public void execute() {
    abcStock.buy();
  }
}

// 创建实现了 Order 接口的实体类:卖出股票
class SellStock implements Order {
  private Stock abcStock;

  public SellStock(Stock abcStock) {
    this.abcStock = abcStock;
  }

  public void execute() {
    abcStock.sell();
  }
}

// 创建命令调用类
class Broker {
  private List<Order> orderList = new ArrayList<Order>();

  public void takeOrder(Order order) {
    orderList.add(order);
  }

  public void placeOrders() {
    for (Order order : orderList) {
      order.execute();
    }
    orderList.clear();
  }
}

// 使用示例
public class CommandPatternDemo {
  public static void main(String[] args) {
    // 使用 Broker 类来接受并执行命令
    Stock abcStock = new Stock();

    BuyStock buyStockOrder = new BuyStock(abcStock);
    SellStock sellStockOrder = new SellStock(abcStock);

    Broker broker = new Broker();
    broker.takeOrder(buyStockOrder);
    broker.takeOrder(sellStockOrder);

    broker.placeOrders();
  }
}
  • 执行程序,输出结果:
Stock [ Name: ABC, Quantity: 10 ] bought
Stock [ Name: ABC, Quantity: 10 ] sold

5 总结

  • 命令模式通过将请求封装为对象,实现了请求发送者和接收者的解耦,提高了系统的灵活性和扩展性。命令模式适用于操作需要撤销和重做、请求的发送者和接收者需要解耦以及支持宏命令的场景。尽管命令模式增加了类的数量和系统的复杂性,但它在实现请求的灵活处理、扩展新功能以及支持复杂操作组合等方面具有显著优势。在实际应用中,需要根据具体需求合理使用命令模式,以实现灵活可扩展的系统设计。