1. 程式人生 > >設計模式-15命令模式(Command Pattern)

設計模式-15命令模式(Command Pattern)

# 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。 **缺點** - 使用命令模式可能會導致某些系統有過多的具體命令類。因為針對每一個命令都需要設計一個具體命令類,因此某些系統可能需要大量具體命令類,這將影響命令模式的