設計模式-15命令模式(Command Pattern)
阿新 • • 發佈:2020-03-13
# 1.模式動機
在軟體設計中,我們經常需要向某些物件傳送請求,但是並不知道請求的接收者是誰,也不知道被請求的操作是哪個,我們只需在程式執行時指定具體的請求接收者即可,此時,可以使用命令模式來進行設計,使得請求傳送者與請求接收者消除彼此之間的耦合,讓物件之間的呼叫關係更加靈活。
命令模式可以對傳送者和接收者完全解耦,傳送者與接收者之間沒有直接引用關係,傳送請求的物件只需要知道如何傳送請求,而不必知道如何完成請求。這就是命令模式的模式動機。
# 2.模式定義
命令模式(Command Pattern):將一個請求封裝為一個物件,從而使我們可用不同的請求對客戶進行引數化;對請求排隊或者記錄請求日誌,以及支援可撤銷的操作。
命令模式是一種**物件行為型模式**,其別名為動作(Action)模式或事務(Transaction)模式。
# 3.模式結構
- 抽象命令類(Command):宣告執行命令的介面,擁有執行命令的抽象方法 execute()。
- 具體命令角色(Concrete Command):是抽象命令類的具體實現類,它擁有接收者物件,並通過呼叫接收者的功能來完成命令要執行的操作。
- 實現者/接收者(Receiver):執行命令功能的相關操作,是具體命令物件業務的真正實現者。
- 呼叫者/請求者(Invoker):是請求的傳送者,它通常擁有很多的命令物件,並通過訪問命令物件來執行相關請求,它不直接訪問接收者。
具體呼叫順序為 Client => Invoker => Concreate Command => Receiver。
Invoker 並不直接呼叫 Receiver,而是通過具體命令物件來呼叫實現者。
# 4.模式程式碼
```java
# 實現者/接受者
public class Receiver {
public void action() {
System.out.println("接受者的 Action 方法");
}
}
# 抽象命令類
public abstract class Command {
public abstract void execute();
}
# 具體命令類,內部 new 了一個實現者的物件
public class ConcreteCommand extends Command {
private Receiver receiver;
public ConcreteCommand() {
this.receiver = new Receiver();
}
@Override
public void execute() {
receiver.action();
}
}
# 呼叫者/請求者,通過賦予不同的 command 值來呼叫不同的的 command
public class Invoker {
private Command command;
public Invoker(Command command) {
this.command = command;
}
public void setCommand(Command command) {
this.command = command;
}
public void call() {
System.out.println("call 執行命令 Command");
command.execute();
}
}
# Client
public class Client {
public static void main(String[] args) {
Command cmd = new ConcreteCommand();
Invoker invoker = new Invoker(cmd);
invoker.call();
}
}
```
首先把它們的呼叫關係理清楚了就明白這個模式了。
# 5.總結
**分析**
命令模式的本質是對命令進行封裝,將發出命令的責任和執行命令的責任分割開。
- 每一個命令都是一個操作:請求的一方發出請求,要求執行一個操作;接收的一方收到請求,並執行操作。
- 命令模式允許請求的一方和接收的一方獨立開來,使得請求的一方不必知道接收請求的一方的介面,更不必知道請求是怎麼被接收,以及操作是否被執行、何時被執行,以及是怎麼被執行的。
- 命令模式使請求本身成為一個物件,這個物件和其他物件一樣可以被儲存和傳遞。
- 命令模式的關鍵在於引入了抽象命令介面,且傳送者針對抽象命令介面程式設計,只有實現了抽象命令介面的具體命令才能與接收者相關聯。
**優點**
- 降低系統的耦合度。
- 新的命令可以很容易地加入到系統中。
- 可以比較容易地設計一個命令佇列和巨集命令(組合命令)。
- 可以方便地實現對請求的Undo和Redo。
**缺點**
- 使用命令模式可能會導致某些系統有過多的具體命令類。因為針對每一個命令都需要設計一個具體命令類,因此某些系統可能需要大量具體命令類,這將影響命令模式的