## 引入
在閻宏博士的《JAVA與模式》一書中開頭是這樣描述命令(Command)模式的:
> 命令模式屬于對象的行為模式。命令模式又稱為行動(Action)模式或交易(Transaction)模式。
命令模式把一個請求或者操作封裝到一個對象中。命令模式允許系統使用不同的請求把客戶端參數化,對請求排隊或者記錄請求日志,可以提供命令的撤銷和恢復功能。
## 定義
命令模式將請求封裝成對象,以便使用不同的請求、隊列或者日志來參數化其他對象。命令模式支持可撤銷的操作。
命令模式可以對發送者額接受者完全解耦,發送者也接收者之間并沒有直接的聯系,發送者只需要知道如何發送請求,不需要關心請求是如何完成了。這就是命令模式,命令模式將方法調用給封裝起來了。
## 結構
命令模式是對命令的封裝。命令模式把發出命令的責任和執行命令的責任分割開,委派給不同的對象。
每一個命令都是一個操作:請求的一方發出請求要求執行一個操作;接收的一方收到請求,并執行操作。命令模式允許請求的一方和接收的一方獨立開來,使得請求的一方不必知道接收請求的一方的接口,更不必知道請求是怎么被接收,以及操作是否被執行、何時被執行,以及是怎么被執行的。命令允許請求的一方和接收請求的一方能夠獨立演化。
下面以一個示意性的系統,說明命令模式的結構。

命令模式涉及到五個角色,它們分別是:
* 客戶端(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