行为型-Command

简介: 命令模式的原理解读命令模式的英文翻译是 Command Design Pattern。在 GoF 的《设计模式》一书中,它是这么定义的: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.

命令模式的原理解读



命令模式的英文翻译是 Command Design Pattern。在 GoF 的《设计模式》一书中,它是这么定义的:


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 策略模式


在策略模式中,不同的策略具有相同的目的、不同的实现、互相之间可以替换。比如,BubbleSort、SelectionSort 都是为了实现排序的,只不过一个是用冒泡排序算法来实现的,另一个是用选择排序算法来实现的。而在命令模式中,不同的命令具有不同的目的,对应不同的处理逻辑,并且互相之间不可替换。


命令模式在平时工作中并不常用,你稍微了解一下就可以。今天,我重点讲解了它的设计意图,也就是能解决什么问题。落实到编码实现,命令模式用到最核心的实现手段,就是将函数封装成对象。我们知道,在大部分编程语言中,函数是没法作为参数传递给其他函数的,也没法赋值给变量。借助命令模式,我们将函数封装成对象,这样就可以实现把函数像对象一样使用。命令模式的主要作用和应用场景,是用来控制命令的执行,比如,异步、延迟、排队执行命令、撤销重做命令、存储命令、给命令记录日志等等,这才是命令模式能发挥独一无二作用的地方。


参考



设计模式之美设计模式代码重构-极客时间


https://time.geekbang.org/column/intro/250


目录
相关文章
|
9月前
|
设计模式 语音技术
设计模式12 - 命令模式【Command Pattern】
设计模式12 - 命令模式【Command Pattern】
37 0
|
2月前
|
设计模式 Java
设计模式-命令模式(Command)
设计模式-命令模式(Command)
37 0
|
9月前
|
设计模式 Java
设计模式~命令模式(Command)-18
目录 十八 命令模式(Command) (1)优点: (2)缺点: (3)使用场景: (4)注意事项: (5)应用实例: 代码 十八 命令模式(Co
37 0
|
SQL 设计模式 Java
Java设计模式-命令模式(Command)
Java设计模式-命令模式(Command)
|
存储 Java 程序员
行为型模式 - 命令模式(Command Pattern)
行为型模式 - 命令模式(Command Pattern)
|
设计模式 Java
浅谈JAVA设计模式之——命令模式(Command)
将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可撤消的操作。
294 0
浅谈JAVA设计模式之——命令模式(Command)
|
C# 设计模式 程序员
C#设计模式(15)——命令模式(Command Pattern)
原文:C#设计模式(15)——命令模式(Command Pattern) 一、前言   之前一直在忙于工作上的事情,关于设计模式系列一直没更新,最近项目中发现,对于设计模式的了解是必不可少的,当然对于设计模式的应用那更是重要,可以说是否懂得应用设计模式在项目中是衡量一个程序员的技术水平,因为对于一个功能的实现,高级工程师和初级工程师一样都会实现,但是区别在于它们实现功能的可扩展和可维护性,也就是代码的是否“优美”、可读。
1131 0