[设计模式]命令模式概述

Posted zhuangmingnan

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[设计模式]命令模式概述相关的知识,希望对你有一定的参考价值。

主要是从 Head Fisrt 设计模式中学习到知识;

1. 定义命令模式

  命令模式将“请求”封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式也支持可撤销的操作。

  讲明白点就是,命令模式有点类似 http的”请求-响应“模型,外部调用者不需要知道命令内部如何,客户端只需要发起请求,就能得到响应,有人想要说,这不是面向对象的封装的概念吗,但是命令模式更像是一种行为类模式,实现低耦合的目标,处理将命令封装成接口,还引入了请求者、接受者的概念,这些会在下面了解到。

  优点:

    • 调用者和接收者彼此之间松耦合,调用者不会持有接收者的引用,只是知道命令中封装了接收者的信息,需要完成这个命令的时候直接调用命令的execute()即可;
    • 符合设计模式的“开-闭原则”,1. 当加入新的命令和命令接收者的时候,调用者可以不修改代码直接访问该命令; 2. 当加入新的调用者的时候,不需要修改命令和命令接收者的代码,调用者可以使用现有的命令;
    • 可以将方便的将多条命令简单封装到一个新的命令,例如 剪切 就可以将 复制、删除两个命令封装起来合并成一个新的命令;
    • 因为命令本身知道接收者的信息,可以将命令进行持久化操作,以便在需要的时候拿出来再次执行,和这个差不多的还有就是命令队列,可以将命令形成一个队列,当系统有资源或者允许的情况下进行命令的取出,调用,控制进行的命令数;
    • 记录命令执行日志,利用调用者记录某个检查点之后的命令操作记录,在丢失前面操作的时候可以通过日志重新恢复,还可以实现撤回、重做的操作;

2. 主要思想

  2.1 操作都封装在一个具体的命令类中,命令持有接收者的引用;

  2.2 调用者直接请求命令的 入口 就可以方便的调用不同的命令;

3. 命令模式的实现

  3.1 下图是命令模式中用到的主要类的类图:

  技术分享图片

  其中Client是客户端请求,Invoker是请求者, Command是命令接口, ConcreteCommand是具体的命令类,其中持有 Receiver(接受者)的引用,Client请求Invoker调用命令,Invoker获得需要的命令之后,执行execute()方法,ConcreteCommand 调用设置好的接受者的一系列方法,完成命令请求,在这一些列请求中,只有ConcreteCommand知道具体的命令执行者是谁,其他角色都是不知道的,只知道调用该命令就能完成自己想要的操作,后面加入新的命令,只要告诉调用者,调用者能不修改代码就能直接调用新的命令,如果加入新的调用者,那么前面调用者能使用的命令,新的调用者都是可以使用的。

  3.2 下面是命令模式的具体代码实现

   这是命令类接口,用来交互的接口:

public interface Command {
  public void execute();
}

  这是具体的命令,具体的命令决定命令真正的执行者和执行的内容:  

public class ConcreteCommand implements Command{
  private Receiver receiver;

  public void execute() {
     recevier.action1();
     receiver.action2();
  }
}

  这是命令的调用者,调用者可以持有一系列命令,并提供出来接口供用户使用:

public class Invoker {
  List<Command> commands;

  public Invoker(List<Command> commands){
    this.commands = commands;
  }       

  public void addCommand(Command command){
    this.commands.add(command);
  }

// 这里采用下标的方式,实际中会提供多个接口或者更加可读的调用方式
  public void doIt(int slot){
     commands.get(slot).execute();
  }

}

  这是接收者代码,接收者提供他能提供的一系列动作集合,供给命令调用:

public class Receiver {
  public void action1(){}

  public void action2(){}

  public void action3(){}
}

  命令模式还能通过记录操作日志的方式来实现重做和撤销的操作,还可以通过组合多个命令的形式,实现宏操作;

总结:

  命令模式将请求者和接收者完全解耦, 通过传递命令接口来实现对功能的请求,可以对代码很少修改或者不修改就可以添加新的命令和调用者,还可以实现命令队列、持久化,重做,撤销,组合等功能;缺点就是每一个操作都需要一个命令类的封装,会造成系统中有很多类的存在。

 

写得比较好的文章:

[解析Java设计模式编程中命令模式的使用] https://www.jb51.net/article/79500.htm

[命令模式 | 菜鸟教程] http://www.runoob.com/design-pattern/command-pattern.html

以上是关于[设计模式]命令模式概述的主要内容,如果未能解决你的问题,请参考以下文章

命令模式

设计模式 设计模式概述

如何运用领域驱动设计 - 值对象

用于从 cloudkit 检索单列的代码模式/片段

是否有在单个活动中处理多个片段的 Android 设计模式?

设计模式-命令模式(Command)