學(xué)校教育網(wǎng)站模板惡意點(diǎn)擊推廣神器
命令模式(Command Pattern)是一種行為型設(shè)計(jì)模式,它旨在將請(qǐng)求發(fā)送者和接收者解耦,通過(guò)將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象,從而允許參數(shù)化客戶(hù)端對(duì)象以進(jìn)行不同的請(qǐng)求、排隊(duì)請(qǐng)求或記錄請(qǐng)求,并支持可撤銷(xiāo)操作。
在軟件開(kāi)發(fā)中,經(jīng)常會(huì)遇到需要將操作請(qǐng)求和操作的具體實(shí)現(xiàn)相分離的場(chǎng)景。比如在一個(gè)圖形編輯軟件里,用戶(hù)可能執(zhí)行繪制圖形、移動(dòng)圖形、刪除圖形等多種操作。如果將這些操作的發(fā)起和具體執(zhí)行邏輯緊密耦合在一起,會(huì)使代碼的可維護(hù)性和擴(kuò)展性變差。命令模式就是為了解決這類(lèi)問(wèn)題而誕生的,它把對(duì)操作的請(qǐng)求封裝成獨(dú)立的對(duì)象,使得我們可以像處理其他數(shù)據(jù)一樣來(lái)處理這些操作請(qǐng)求。
一、核心思想
命令模式的核心在于將一個(gè)請(qǐng)求(命令)封裝為一個(gè)對(duì)象。這樣做的好處是可以將請(qǐng)求參數(shù)化,方便對(duì)請(qǐng)求進(jìn)行存儲(chǔ)、傳遞、調(diào)用、排隊(duì)、記錄日志以及支持撤銷(xiāo)和重做等操作。通過(guò)這種方式,把發(fā)出命令的責(zé)任和執(zhí)行命令的責(zé)任分割開(kāi),降低了系統(tǒng)模塊之間的耦合度。
二、定義與結(jié)構(gòu)
- 定義:將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象,從而使你可以用不同的請(qǐng)求對(duì)客戶(hù)進(jìn)行參數(shù)化;對(duì)請(qǐng)求排隊(duì)或者記錄請(qǐng)求日志,以及支持可撤銷(xiāo)的操作。
- 結(jié)構(gòu)
- Command(命令):這是一個(gè)抽象類(lèi)或接口,聲明了執(zhí)行操作的抽象方法execute()。
- ConcreteCommand(具體命令):實(shí)現(xiàn)了Command接口,它知道具體的接收者對(duì)象,并在execute方法中調(diào)用接收者的相應(yīng)操作方法。
- Receiver(接收者):負(fù)責(zé)執(zhí)行命令所要求的具體操作,它包含了真正實(shí)現(xiàn)業(yè)務(wù)邏輯的代碼。
- Invoker(調(diào)用者):負(fù)責(zé)調(diào)用命令對(duì)象執(zhí)行請(qǐng)求,它持有一個(gè)命令對(duì)象的引用,通過(guò)調(diào)用命令對(duì)象的execute方法來(lái)觸發(fā)操作。
三、角色
- 命令(Command):為所有具體命令類(lèi)定義了統(tǒng)一的接口,使得調(diào)用者可以統(tǒng)一地調(diào)用命令的執(zhí)行方法。
- 具體命令(ConcreteCommand):將一個(gè)接收者對(duì)象和一個(gè)動(dòng)作綁定,在執(zhí)行execute方法時(shí),調(diào)用接收者的相應(yīng)動(dòng)作。
- 接收者(Receiver):知曉如何執(zhí)行與請(qǐng)求相關(guān)的具體操作,是命令真正的執(zhí)行者。
- 調(diào)用者(Invoker):負(fù)責(zé)安排命令的執(zhí)行,它并不關(guān)心命令的具體實(shí)現(xiàn),只關(guān)心如何觸發(fā)命令的執(zhí)行。
四、實(shí)現(xiàn)步驟及代碼示例
- 定義命令接口
public interface Command {void execute();
}
- 定義接收者類(lèi)
public class Light {public void on() {System.out.println("Light is on");}public void off() {System.out.println("Light is off");}
}
- 定義具體命令類(lèi)
public class LightOnCommand implements Command {private Light light;public LightOnCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.on();}
}public class LightOffCommand implements Command {private Light light;public LightOffCommand(Light light) {this.light = light;}@Overridepublic void execute() {light.off();}
}
- 定義調(diào)用者類(lèi)
public class RemoteControl {private Command command;public RemoteControl(Command command) {this.command = command;}public void pressButton() {command.execute();}
}
- 測(cè)試代碼
public class Main {public static void main(String[] args) {Light light = new Light();Command lightOnCommand = new LightOnCommand(light);Command lightOffCommand = new LightOffCommand(light);RemoteControl onRemote = new RemoteControl(lightOnCommand);RemoteControl offRemote = new RemoteControl(lightOffCommand);onRemote.pressButton();offRemote.pressButton();}
}
五、常見(jiàn)技術(shù)框架應(yīng)用
JavaScript 實(shí)現(xiàn)命令模式:
// 接收者
function Door() {this.open = function () {console.log('Door is opened');};this.close = function () {console.log('Door is closed');};
}// 命令接口
function Command(door) {this.door = door;
}// 具體命令
function OpenDoorCommand(door) {Command.call(this, door);this.execute = function () {this.door.open();};
}function CloseDoorCommand(door) {Command.call(this, door);this.execute = function () {this.door.close();};
}// 調(diào)用者
function Remote(door) {this.command = null;this.setCommand = function (command) {this.command = command;};this.pressButton = function () {if (this.command) {this.command.execute();}};
}// 使用示例
let door = new Door();
let openCommand = new OpenDoorCommand(door);
let closeCommand = new CloseDoorCommand(door);let remote = new Remote(door);
remote.setCommand(openCommand);
remote.pressButton();remote.setCommand(closeCommand);
remote.pressButton();
六、應(yīng)用場(chǎng)景
當(dāng)你需要在不同的時(shí)刻指定、排列和執(zhí)行請(qǐng)求的時(shí)候。
當(dāng)你需要支持命令的撤銷(xiāo)(Undo)功能時(shí)。
當(dāng)你需要將請(qǐng)求作為對(duì)象進(jìn)行傳遞和操作時(shí)。
當(dāng)你需要組合多個(gè)操作形成宏命令時(shí)。
- 遙控器控制:如上面的示例所示,可以用命令模式實(shí)現(xiàn)遙控器來(lái)控制不同的家電設(shè)備,如電視、音響和燈。
- 文本編輯器操作:文本編輯器中的撤銷(xiāo)、重做、剪切、復(fù)制、粘貼等操作可以使用命令模式來(lái)實(shí)現(xiàn)。
- 菜單系統(tǒng):圖形用戶(hù)界面(GUI)應(yīng)用中的菜單項(xiàng)和按鈕操作可以通過(guò)命令模式來(lái)處理。
- 游戲中的動(dòng)作:在游戲中,角色的動(dòng)作和命令(如攻擊、防御、跳躍等)可以使用命令模式來(lái)處理。
- 多級(jí)撤銷(xiāo)操作:命令模式支持撤銷(xiāo)和重做操作,因此在需要多級(jí)撤銷(xiāo)的應(yīng)用中很有用,如圖像編輯器或CAD軟件。
- 日程安排應(yīng)用:在日程安排應(yīng)用中,可以使用命令模式來(lái)處理添加、編輯、刪除事件等操作。
七、優(yōu)缺點(diǎn)
優(yōu)點(diǎn)
- 解耦調(diào)用者和接收者:調(diào)用者和接收者之間通過(guò)命令對(duì)象進(jìn)行交互,調(diào)用者無(wú)需了解接收者的具體實(shí)現(xiàn)細(xì)節(jié),降低了模塊之間的耦合度。
- 支持命令的擴(kuò)展和組合:可以很方便地定義新的命令類(lèi),也可以將多個(gè)命令組合成一個(gè)復(fù)合命令,以實(shí)現(xiàn)更復(fù)雜的功能。
- 便于實(shí)現(xiàn)撤銷(xiāo)和重做:通過(guò)在命令對(duì)象中保存操作的相關(guān)狀態(tài)信息,可以很方便地實(shí)現(xiàn)操作的撤銷(xiāo)和重做功能。
缺點(diǎn)
- 增加系統(tǒng)復(fù)雜度:由于引入了命令對(duì)象和相關(guān)的類(lèi),會(huì)增加系統(tǒng)的類(lèi)和對(duì)象數(shù)量,導(dǎo)致系統(tǒng)復(fù)雜度上升,尤其是在命令種類(lèi)繁多的情況下。
- 性能開(kāi)銷(xiāo):命令的封裝和傳遞會(huì)帶來(lái)一定的性能開(kāi)銷(xiāo),在對(duì)性能要求極高的場(chǎng)景下,需要謹(jǐn)慎評(píng)估是否適合使用命令模式。