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