71 - 命令模式

2021-10-10  本文已影响0人  舍是境界

学习命令模式的过程中,你可能会遇到的最大的疑惑是,感觉命令模式没啥用,是一种过度设计,有更加简单的设计思路可以替代。所以,本文的重点是这个模式的设计意图,带你搞清楚到底什么情况下才真正需要使用它

命令模式的原理解读

The command pattern encapsulates a request as an object, thereby letting us parameterize other objects with different requests, queue or log requests, and support undoable operations.
命令模式将请求(命令)封装为一个对象,这样可以使用不同的请求参数化其他对象(将不同请求依赖注入到其他对象),并且能够支持请求(命令)的排队执行、记录日志、撤销等(附加控制)功能。

命令模式实战

public interface Command {
  void execute();
}
public class GotDiamondCommand implements Command {
  // 省略成员变量
  public GotDiamondCommand(/*数据*/) {
    //...
  }
  @Override
  public void execute() {
    // 执行相应的逻辑
  }
}
//GotStartCommand/HitObstacleCommand/ArchiveCommand类省略
public class GameApplication {
  private static final int MAX_HANDLED_REQ_COUNT_PER_LOOP = 100;
  private Queue<Command> queue = new LinkedList<>();
  public void mainloop() {
    while (true) {
      List<Request> requests = new ArrayList<>();
      
      //省略从epoll或者select中获取数据,并封装成Request的逻辑,
      //注意设置超时时间,如果很长时间没有接收到请求,就继续下面的逻辑处理。
      
      for (Request request : requests) {
        Event event = request.getEvent();
        Command command = null;
        if (event.equals(Event.GOT_DIAMOND)) {
          command = new GotDiamondCommand(/*数据*/);
        } else if (event.equals(Event.GOT_STAR)) {
          command = new GotStartCommand(/*数据*/);
        } else if (event.equals(Event.HIT_OBSTACLE)) {
          command = new HitObstacleCommand(/*数据*/);
        } else if (event.equals(Event.ARCHIVE)) {
          command = new ArchiveCommand(/*数据*/);
        } // ...一堆else if...
        queue.add(command);
      }
      int handledCount = 0;
      while (handledCount < MAX_HANDLED_REQ_COUNT_PER_LOOP) {
        if (queue.isEmpty()) {
          break;
        }
        Command command = queue.poll();
        command.execute();
      }
    }
  }
}

命令模式 VS 策略模式

小结

上一篇下一篇

猜你喜欢

热点阅读