Java 设计模式之命令模式
一、了解命令模式
1.1 什么是命令模式
命令模式將“請求”封裝成對象,以便使用不同的請求、隊列或者日志來參數化其他對象。命令模式也支持可撤銷的操作。這種說法比較難以理解,換種說法就是指:
在軟件系統中,“行為請求者”與“行為實現者”通常呈現一種“緊耦合”。但在某些場合,比如要對行為進行“記錄、撤銷/重做、事務”等處理,這種無法抵御變化的緊耦合是不合適的。
在這種情況下,如何將“行為請求者”與“行為實現者”解耦?將一組行為抽象為對象,實現二者之間的松耦合。這就是命令模式(Command Pattern)。
1.2 命令模式組成結構
- 命令接口 (Command):定義命令的接口,聲明執行的方法。
- 具體命令 (ConcreteCommand):命令接口實現對象,是“虛”的實現;通常會持有接收者,并調用接收者的功能來完成命令要執行的操作。
- 接受者 (Receiver):接收者,真正執行命令的對象。任何類都可能成為一個接收者,只要它能夠實現命令要求實現的相應功能。
- 調用者 (Invoker):要求命令對象執行請求,通常會持有命令對象,可以持有很多的命令對象。這個是客戶端真正觸發命令并要求命令執行相應操作的地方,也就是說相當于使用命令對象的入口。
- 客戶 (Client):創建具體的命令對象,并且設置命令對象的接收者。注意這個不是我們常規意義上的客戶端,而是在組裝命令對象和接收者,或許,把這個 Client 稱為裝配者會更好理解,因為真正使用命令的客戶端是從 Invoker 來觸發執行。
1.3 命令模式 UML 圖解
1.4 命令模式適用場景
- 系統需要將請求調用者和請求接收者解耦,使得調用者和接收者不直接交互。
- 系統需要在不同的時間指定請求、將請求排隊和執行請求。
- 系統需要支持命令的撤銷 (Undo) 操作和恢復 (Redo) 操作。
- 系統需要將一組操作組合在一起,即支持宏命令。
二、命令模式具體應用
2.1 問題描述
電燈遙控器:現在讓你為一種新型電燈設計一種手持的遠程遙控器,這個遙控器可以打開和關閉電燈。
2.2 問題分析設計設計圖
2.3 代碼實現
接收者 Light 類
package com.jas.command; /*** 電燈提供打開和關閉的功能*/ public class Light {void on(){System.out.println("Light is on!");}void off(){ System.out.println("Light is off!"); } }命令接口 Command
package com.jas.command; /*** 所有的命令對象都應該實現的接口,提供了一個執行的方法。*/ public interface Command {void execute(); }具體命令 LightOnCommand 類
package com.jas.command;public class LightOnCommand implements Command {Light light;/*** 通過構造器實力化 light 對象,在 execute() 方法中調用其對應的打開與關閉方法* * @param light 電燈對象*/public LightOnCommand(Light light){this.light = light;}/*** 調用電燈打開的方法*/@Overridepublic void execute() {light.on();} }具體命令 LightOffCommand 類
package com.jas.command;public class LightOffCommand implements Command {Light light;public LightOffCommand(Light light){this.light = light;}/*** 調用電燈關閉的方法*/@Overridepublic void execute() {light.off();} }調用者 RemoteControl 類 (遙控器)
package com.jas.command;public class RemoteControl {Command onCommand;Command offComand;public RemoteControl(){}/*** 傳入一組命令* * @param onCommand 打開電燈的命令對象* @param offComand 關閉電燈的命令對象*/public void setCommand(Command onCommand, Command offComand){this.onCommand = onCommand;this.offComand = offComand;}/*** 打開電燈的按鈕,通過 onCommand 調用 execute() 方法*/public void onButtonWasPushed(){//execute() 方法中封裝了打開電燈的方法onCommand.execute();}/*** 關閉電燈的按鈕,通過 offComand 調用 execute() 方法*/public void offButtonWasPushed(){//execute() 方法中封裝了關閉電燈的方法offComand.execute();} }客戶 RemoteLoader 類
package com.jas.command;public class RemoteLoader {public static void main(String[] args) {// 定義一個遠程遙控器RemoteControl remoteControl = new RemoteControl();// 定義一個電燈對象Light light = new Light();// 打開電燈的命令對象Command onCommand = new LightOnCommand(light);// 關閉電燈的命令對象Command offCommand = new LightOffCommand(light);remoteControl.setCommand(onCommand,offCommand);remoteControl.onButtonWasPushed();remoteControl.offButtonWasPushed();} }/*** 輸出* Light is on!* Light is off!*/三、命令模式總結
3.1 命令模式優缺點
優點
- 降低對象之間的耦合度。
- 新的命令可以很容易地加入到系統中。
- 可以比較容易地設計一個組合命令。
- 調用同一方法實現不同的功能。
缺點
使用命令模式可能會導致某些系統有過多的具體命令類。因為針對每一個命令都需要設計一個具體命令類,因此某些系統可能需要大量具體命令類,這將影響命令模式的使用。
3.2 命令模式知識點總結
PS:可以參考上面的例子進行知識回顧加深。
- 命令模式將發出請求的對象和執行請求的對象解耦。
- 在被解耦的兩者之間是通過命令對象進行溝通的。命令對象封裝了具體接收者和一個或一組動作。
- 調用者通過命令對象的 execute() 發出請求,這會使接收者的動作被調用。
- 調用者可以接收命令對象當做參數,甚至是在運行時動態的進行。
- 命令可以支持撤銷 (undo),做法是實現一個 undo() 方法,可以回到 execute() 方法執行前的狀態。
- 命令也可以用來實現日志和系統事務。
PS:點擊了解更多設計模式 http://blog.csdn.net/codejas/article/details/79236013
參考文獻
《Head First 設計模式》
總結
以上是生活随笔為你收集整理的Java 设计模式之命令模式的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 寓意好的网名
- 下一篇: Java 设计模式之适配器模式