命令模式:請求以命令的形式包裹在對象中,並傳給調用對象。調用對象尋找能夠處理該命令的合適的對象,並把該命令傳給相應的對象,該對象執行命令。
生活小栗子:客戶下單,訂單記錄了客戶購買的產品,倉庫根據訂單給客戶備貨。javascript
命令模式由三種角色構成:java
invoker
(發出命令,調用命令對象,不知道如何執行與誰執行);receiver
(提供對應接口處理請求,不知道誰發起請求);command
(接收命令,調用接收者對應接口處理髮布者的請求)。發佈者 invoker
和接收者 receiver
各自獨立,將請求封裝成命令對象 command
,請求的具體執行由命令對象 command
調用接收者 receiver
對應接口執行。git
命令對象 command
充當發佈者 invoker
與接收者 receiver
之間的鏈接橋樑(中間對象介入)。實現發佈者與接收之間的解耦,對比過程化請求調用,命令對象 command
擁有更長的生命週期,接收者 receiver
屬性方法被封裝在命令對象 command
屬性中,使得程序執行時可任意時刻調用接收者對象 receiver
。所以 command
可對請求進行進一步管控處理,如實現延時、預約、排隊、撤銷等功能。github
class Receiver { // 接收者類 execute() { console.log('接收者執行請求'); } } class Command { // 命令對象類 constructor(receiver) { this.receiver = receiver; } execute () { // 調用接收者對應接口執行 console.log('命令對象->接收者->對應接口執行'); this.receiver.execute(); } } class Invoker { // 發佈者類 constructor(command) { this.command = command; } invoke() { // 發佈請求,調用命令對象 console.log('發佈者發佈請求'); this.command.execute(); } } const warehouse = new Receiver(); // 倉庫 const order = new Command(warehouse); // 訂單 const client = new Invoker(order); // 客戶 client.invoke(); /* 輸出: 發佈者發佈請求 命令對象->接收者->對應接口執行 接收者執行請求 */
有時候須要向某些對象發送請求,可是並不知道請求的接收者是誰,也不知道被請求的操做是什麼。須要一種鬆耦合的方式來設計程序,使得發送者和接收者可以消除彼此之間的耦合關係。
——《JavaScript 設計模式與開發實踐》
優勢:算法
缺點:設計模式
宏命令:一組命令集合(命令模式與組合模式的產物)
發佈者發佈一個請求,命令對象會遍歷命令集合下的一系列子命令並執行,完成多任務。緩存
// 宏命令對象 class MacroCommand { constructor() { this.commandList = []; // 緩存子命令對象 } add(command) { // 向緩存中添加子命令 this.commandList.push(command); } exceute() { // 對外命令執行接口 // 遍歷自命令對象並執行其 execute 方法 for (const command of this.commandList) { command.execute(); } } } const openWechat = { // 命令對象 execute: () => { console.log('打開微信'); } }; const openChrome = { // 命令對象 execute: () => { console.log('打開Chrome'); } }; const openEmail = { // 命令對象 execute: () => { console.log('打開Email'); } } const macroCommand = new MacroCommand(); macroCommand.add(openWechat); // 宏命令中添加子命令 macroCommand.add(openChrome); // 宏命令中添加子命令 macroCommand.add(openEmail); // 宏命令中添加子命令 macroCommand.execute(); // 執行宏命令 /* 輸出: 打開微信 打開Chrome 打開Email */
傻瓜命令:命令對象須要接收者來執行客戶的請求。智能命令:命令對象直接實現請求,不須要接收者,「聰明」的命令對象。微信
「傻瓜命令」 與 「智能命令」 的區別在因而否有 「接收者」 對象。this
// openWechat 是智能命令對象,並無傳入 receiver 接收對象 const openWechat = { execute: () => { // 命令對象直接處理請求 console.log('打開微信'); } };
沒有 「接收者」 的智能命令與策略模式很相似。代碼實現相似,區別在於實現目標不一樣。spa
參考文章
本文首發Github,期待Star!
https://github.com/ZengLingYong/blog
做者:以樂之名 本文原創,有不當的地方歡迎指出。轉載請指明出處。