## 引入
在阎宏博士的《JAVA与模式》一书中开头是这样描述命令(Command)模式的:
> 命令模式属于对象的行为模式。命令模式又称为行动(Action)模式或交易(Transaction)模式。
命令模式把一个请求或者操作封装到一个对象中。命令模式允许系统使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。
## 定义
命令模式将请求封装成对象,以便使用不同的请求、队列或者日志来参数化其他对象。命令模式支持可撤销的操作。
命令模式可以对发送者额接受者完全解耦,发送者也接收者之间并没有直接的联系,发送者只需要知道如何发送请求,不需要关心请求是如何完成了。这就是命令模式,命令模式将方法调用给封装起来了。
## 结构
命令模式是对命令的封装。命令模式把发出命令的责任和执行命令的责任分割开,委派给不同的对象。
每一个命令都是一个操作:请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行操作。命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。命令允许请求的一方和接收请求的一方能够独立演化。
下面以一个示意性的系统,说明命令模式的结构。
![](https://box.kancloud.cn/c1fb12b9898a984584402945a007f88f_583x226.png)
命令模式涉及到五个角色,它们分别是:
* 客户端(Client)角色:创建一个具体命令(ConcreteCommand)对象并确定其接收者。
* 命令(Command)角色:声明了一个给所有具体命令类的抽象接口。
* 具体命令(ConcreteCommand)角色:定义一个接收者和行为之间的弱耦合;实现execute()方法,负责调用接收者的相应操作。execute()方法通常叫做执行方法。
* 请求者(Invoker)角色:负责调用命令对象执行请求,相关的方法叫做行动方法。
* 接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。
## 代码实现
现在有一个bug需要解决,公司Boss下令去让程序员去解决.这个过程是:公司Boss发出命令,命令传递到程序员本人,程序员解决bug.使用命令模式使得三者相互解耦,这样Boss不需要知道是怎么做的,也不需要知道是哪一个程序员做的.只需要知道bug修改好了就可以了。
执行者角色
```
public class Receiver {
private String name;
public Receiver(String name){
this.name = name;
}
//执行者的执行方法
public void operator(){
System.out.println(name + " 已经接收到命令,开始执行");
}
}
```
命令角色接口
```
public interface Command {
public void execute();
}
```
具体命令角色角色类
```
public class ConcreteCommand implements Command {
private Receiver receiver;
public ConcreteCommand(Receiver receiver){
this.receiver = receiver;
}
@Override
public void execute() {
//调用执行者的执行方法
receiver.operator();
}
}
```
请求者角色类
```
public class Invoker {
private Command command;
public Invoker(Command command) {
this.command = command;
}
//boss发出命令的方法
public void action() {
command.execute();
}
}
```
测试类
```
public class CommandTest {
public static void main(String[] args) {
//创建一个程序员 name = "坑露"
Receiver programmer = new Receiver("坑露");
//为这个命令指定一个执行者
Command command = new ConcreteCommand(programmer);
//为这个命令指定一个调用者
Invoker boss = new Invoker(command);
//执行
boss.action();
}
}
```
## 优点
* 更松散的耦合
命令模式使得发起命令的对象——客户端,和具体实现命令的对象——接收者对象完全解耦,也就是说发起命令的对象完全不知道具体实现对象是谁,也不知道如何实现。
* 更动态的控制
命令模式把请求封装起来,可以动态地对它进行参数化、队列化和日志化等操作,从而使得系统更灵活。
* 很自然的复合命令
命令模式中的命令对象能够很容易地组合成复合命令,也就是宏命令,从而使系统操作更简单,功能更强大。
* 更好的扩展性
由于发起命令的对象和具体的实现完全解耦,因此扩展新的命令就很容易,只需要实现新的命令对象,然后在装配的时候,把具体的实现对象设置到命令对象中,然后就可以使用这个命令对象,已有的实现完全不用变化。
## 缺点
* 使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。
## 适用场景
* 1、系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。
* 2、系统需要在不同的时间指定请求、将请求排队和执行请求。
* 3、系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。
* 4、系统需要将一组操作组合在一起,即支持宏命令。
## 总结
* 1、命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开。
* 2、每一个命令都是一个操作:请求的一方发出请求,要求执行一个操作;接收的一方收到请求,并执行操作。
* 3、命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。
* 4、命令模式使请求本身成为一个对象,这个对象和其他对象一样可以被存储和传递。
* 5、命令模式的关键在于引入了抽象命令接口,且发送者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联。
- java
- 设计模式
- 设计模式总览
- 设计原则
- 工厂方法模式
- 抽象工厂模式
- 单例模式
- 建造者模式
- 原型模式
- 适配器模式
- 装饰者模式
- 代理模式
- 外观模式
- 桥接模式
- 组合模式
- 享元模式
- 策略模式
- 模板方法模式
- 观察者模式
- 迭代子模式
- 责任链模式
- 命令模式
- 备忘录模式
- 状态模式
- 访问者模式
- 中介者模式
- 解释器模式
- 附录
- JVM相关
- JVM内存结构
- Java虚拟机的内存组成以及堆内存介绍
- Java堆和栈
- 附录-数据结构的堆栈和内存分配的堆区栈区的区别
- Java内存之Java 堆
- Java内存之虚拟机和内存区域概述
- Java 内存之方法区和运行时常量池
- Java 内存之直接内存(堆外内存)
- JAVA内存模型
- Java内存模型介绍
- 内存模型如何解决缓存一致性问题
- 深入理解Java内存模型——基础
- 深入理解Java内存模型——重排序
- 深入理解Java内存模型——顺序一致性
- 深入理解Java内存模型——volatile
- 深入理解Java内存模型——锁
- 深入理解Java内存模型——final
- 深入理解Java内存模型——总结
- 内存可见性
- JAVA对象模型
- JVM内存结构 VS Java内存模型 VS Java对象模型
- Java的对象模型
- Java的对象头
- HotSpot虚拟机
- HotSpot虚拟机对象探秘
- 深入分析Java的编译原理
- Java虚拟机的锁优化技术
- 对象和数组并不是都在堆上分配内存的
- 垃圾回收
- JVM内存管理及垃圾回收
- JVM 垃圾回收器工作原理及使用实例介绍
- JVM内存回收理论与实现(对象存活的判定)
- JVM参数及调优
- CMS GC日志分析
- JVM实用参数(一)JVM类型以及编译器模式
- JVM实用参数(二)参数分类和即时(JIT)编译器诊断
- JVM实用参数(三)打印所有XX参数及值
- JVM实用参数(四)内存调优
- JVM实用参数(五)新生代垃圾回收
- JVM实用参数(六) 吞吐量收集器
- JVM实用参数(七)CMS收集器
- JVM实用参数(八)GC日志
- Java性能调优原则
- JVM 优化经验总结
- 面试题整理
- 面试题1
- java日志规约
- Spring安全
- OAtuth2.0简介
- Spring Session 简介(一)
- Spring Session 简介(二)
- Spring Session 简介(三)
- Spring Security 简介(一)
- Spring Security 简介(二)
- Spring Security 简介(三)
- Spring Security 简介(四)
- Spring Security 简介(五)
- Spring Security Oauth2 (一)
- Spring Security Oauth2 (二)
- Spring Security Oauth2 (三)
- SpringBoot
- Shiro
- Shiro和Spring Security对比
- Shiro简介
- Session、Cookie和Cache
- Web Socket
- Spring WebFlux