摘要:支持撤銷,隊列,宏命令等功能。宏命令宏命令一組命令集合命令模式與組合模式的產物發布者發布一個請求,命令對象會遍歷命令集合下的一系列子命令并執行,完成多任務。
命令模式:請求以命令的形式包裹在對象中,并傳給調用對象。調用對象尋找可以處理該命令的合適的對象,并把該命令傳給相應的對象,該對象執行命令。
生活小栗子:客戶下單,訂單記錄了客戶購買的產品,倉庫根據訂單給客戶備貨。
模式特點命令模式由三種角色構成:
發布者 invoker(發出命令,調用命令對象,不知道如何執行與誰執行);
接收者 receiver (提供對應接口處理請求,不知道誰發起請求);
命令對象 command(接收命令,調用接收者對應接口處理發布者的請求)。
發布者 invoker 和接收者 receiver 各自獨立,將請求封裝成命令對象 command ,請求的具體執行由命令對象 command 調用接收者 receiver 對應接口執行。
命令對象 command 充當發布者 invoker 與接收者 receiver 之間的連接橋梁(中間對象介入)。實現發布者與接收之間的解耦,對比過程化請求調用,命令對象 command 擁有更長的生命周期,接收者 receiver 屬性方法被封裝在命令對象 command 屬性中,使得程序執行時可任意時刻調用接收者對象 receiver 。因此 command 可對請求進行進一步管控處理,如實現延時、預定、排隊、撤銷等功能。
代碼實現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 */傻瓜命令與智能命令
傻瓜命令:命令對象需要接收者來執行客戶的請求。智能命令:命令對象直接實現請求,不需要接收者,“聰明”的命令對象。
“傻瓜命令” 與 “智能命令” 的區別在于是否有 “接收者” 對象。
// openWechat 是智能命令對象,并沒有傳入 receiver 接收對象 const openWechat = { execute: () => { // 命令對象直接處理請求 console.log("打開微信"); } };
沒有 “接收者” 的智能命令與策略模式很類似。代碼實現類似,區別在于實現目標不同。
策略模式中實現的目標是一致的,只是實現算法不同(如目標:根據KPI計算獎金);
智能命令的解決問題更廣,目標更具散發性。(如目標:計算獎金/計算出勤率等)。
參考文章
《JavaScript 設計模式與開發實踐》
本文首發Github,期待Star!
https://github.com/ZengLingYong/blog
作者:以樂之名
本文原創,有不當的地方歡迎指出。轉載請指明出處。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/105635.html
摘要:裝飾者模式裝飾者模式提供比繼承更有彈性的替代方案。裝飾者用于包裝同接口的對象,用于通過重載方法的形式添加新功能,該模式可以在被裝飾者的前面或后面加上自己的行為以達到特定的目的。簡單的理解給對象動態添加職責的方式稱為裝飾著模式。 裝飾者模式 裝飾者模式提供比繼承更有彈性的替代方案。裝飾者用于包裝同接口的對象,用于通過重載方法的形式添加新功能,該模式可以在被裝飾者的前面或后面加上自己的行為...
摘要:與門面模式的聯系本文要說的適配器模式和上一篇門面模式在思想上有相似之處,所以放在一起說。我們以中的一個為例,說說實際應用中的適配器模式的使用方法。而如果實現層的問題不大,要解決一部分適配問題的話,適配器模式就是很好的選擇了。 與門面模式的聯系 本文要說的適配器模式和上一篇門面模式在思想上有相似之處,所以放在一起說。它們都對類的接口進行了一些改變。門面模式是把相似的或是完成相關任務的接...
摘要:參考鏈接面向對象編程模型現在的很多編程語言基本都具有面向對象的思想,比如等等,而面向對象的主要思想對象,類,繼承,封裝,多態比較容易理解,這里就不多多描述了。 前言 在我們的日常日發和學習生活中會常常遇到一些名詞,比如 命令式編程模型,聲明式編程模型,xxx語言是面向對象的等等,這個編程模型到處可見,但是始終搞不清是什么?什么語言又是什么編程模型,當你新接觸一門語言的時候,有些問題是需...
閱讀 2238·2021-11-15 11:39
閱讀 994·2021-09-26 09:55
閱讀 937·2021-09-04 16:48
閱讀 2846·2021-08-12 13:23
閱讀 927·2021-07-30 15:30
閱讀 2461·2019-08-29 14:16
閱讀 892·2019-08-26 10:15
閱讀 533·2019-08-23 18:40