摘要:支持撤銷(xiāo),隊(duì)列,宏命令等功能。宏命令宏命令一組命令集合命令模式與組合模式的產(chǎn)物發(fā)布者發(fā)布一個(gè)請(qǐng)求,命令對(duì)象會(huì)遍歷命令集合下的一系列子命令并執(zhí)行,完成多任務(wù)。
命令模式:請(qǐng)求以命令的形式包裹在對(duì)象中,并傳給調(diào)用對(duì)象。調(diào)用對(duì)象尋找可以處理該命令的合適的對(duì)象,并把該命令傳給相應(yīng)的對(duì)象,該對(duì)象執(zhí)行命令。
生活小栗子:客戶(hù)下單,訂單記錄了客戶(hù)購(gòu)買(mǎi)的產(chǎn)品,倉(cāng)庫(kù)根據(jù)訂單給客戶(hù)備貨。
模式特點(diǎn)命令模式由三種角色構(gòu)成:
發(fā)布者 invoker(發(fā)出命令,調(diào)用命令對(duì)象,不知道如何執(zhí)行與誰(shuí)執(zhí)行);
接收者 receiver (提供對(duì)應(yīng)接口處理請(qǐng)求,不知道誰(shuí)發(fā)起請(qǐng)求);
命令對(duì)象 command(接收命令,調(diào)用接收者對(duì)應(yīng)接口處理發(fā)布者的請(qǐng)求)。
發(fā)布者 invoker 和接收者 receiver 各自獨(dú)立,將請(qǐng)求封裝成命令對(duì)象 command ,請(qǐng)求的具體執(zhí)行由命令對(duì)象 command 調(diào)用接收者 receiver 對(duì)應(yīng)接口執(zhí)行。
命令對(duì)象 command 充當(dāng)發(fā)布者 invoker 與接收者 receiver 之間的連接橋梁(中間對(duì)象介入)。實(shí)現(xiàn)發(fā)布者與接收之間的解耦,對(duì)比過(guò)程化請(qǐng)求調(diào)用,命令對(duì)象 command 擁有更長(zhǎng)的生命周期,接收者 receiver 屬性方法被封裝在命令對(duì)象 command 屬性中,使得程序執(zhí)行時(shí)可任意時(shí)刻調(diào)用接收者對(duì)象 receiver 。因此 command 可對(duì)請(qǐng)求進(jìn)行進(jìn)一步管控處理,如實(shí)現(xiàn)延時(shí)、預(yù)定、排隊(duì)、撤銷(xiāo)等功能。
代碼實(shí)現(xiàn)class Receiver { // 接收者類(lèi) execute() { console.log("接收者執(zhí)行請(qǐng)求"); } } class Command { // 命令對(duì)象類(lèi) constructor(receiver) { this.receiver = receiver; } execute () { // 調(diào)用接收者對(duì)應(yīng)接口執(zhí)行 console.log("命令對(duì)象->接收者->對(duì)應(yīng)接口執(zhí)行"); this.receiver.execute(); } } class Invoker { // 發(fā)布者類(lèi) constructor(command) { this.command = command; } invoke() { // 發(fā)布請(qǐng)求,調(diào)用命令對(duì)象 console.log("發(fā)布者發(fā)布請(qǐng)求"); this.command.execute(); } } const warehouse = new Receiver(); // 倉(cāng)庫(kù) const order = new Command(warehouse); // 訂單 const client = new Invoker(order); // 客戶(hù) client.invoke(); /* 輸出: 發(fā)布者發(fā)布請(qǐng)求 命令對(duì)象->接收者->對(duì)應(yīng)接口執(zhí)行 接收者執(zhí)行請(qǐng)求 */應(yīng)用場(chǎng)景
有時(shí)候需要向某些對(duì)象發(fā)送請(qǐng)求,但是并不知道請(qǐng)求的接收者是誰(shuí),也不知道被請(qǐng)求的操作是什么。需要一種松耦合的方式來(lái)設(shè)計(jì)程序,使得發(fā)送者和接收者能夠消除彼此之間的耦合關(guān)系。
——《JavaScript 設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐》
不關(guān)注執(zhí)行者,不關(guān)注執(zhí)行過(guò)程;
只要結(jié)果,支持撤銷(xiāo)請(qǐng)求、延后處理、日志記錄等。
優(yōu)缺點(diǎn)
優(yōu)點(diǎn):
發(fā)布者與接收者實(shí)現(xiàn)解耦;
可擴(kuò)展命令,對(duì)請(qǐng)求可進(jìn)行排隊(duì)或日志記錄。(支持撤銷(xiāo),隊(duì)列,宏命令等功能)。
缺點(diǎn):
額外增加命令對(duì)象,非直接調(diào)用,存在一定開(kāi)銷(xiāo)。
宏命令宏命令:一組命令集合(命令模式與組合模式的產(chǎn)物)
發(fā)布者發(fā)布一個(gè)請(qǐng)求,命令對(duì)象會(huì)遍歷命令集合下的一系列子命令并執(zhí)行,完成多任務(wù)。
// 宏命令對(duì)象 class MacroCommand { constructor() { this.commandList = []; // 緩存子命令對(duì)象 } add(command) { // 向緩存中添加子命令 this.commandList.push(command); } exceute() { // 對(duì)外命令執(zhí)行接口 // 遍歷自命令對(duì)象并執(zhí)行其 execute 方法 for (const command of this.commandList) { command.execute(); } } } const openWechat = { // 命令對(duì)象 execute: () => { console.log("打開(kāi)微信"); } }; const openChrome = { // 命令對(duì)象 execute: () => { console.log("打開(kāi)Chrome"); } }; const openEmail = { // 命令對(duì)象 execute: () => { console.log("打開(kāi)Email"); } } const macroCommand = new MacroCommand(); macroCommand.add(openWechat); // 宏命令中添加子命令 macroCommand.add(openChrome); // 宏命令中添加子命令 macroCommand.add(openEmail); // 宏命令中添加子命令 macroCommand.execute(); // 執(zhí)行宏命令 /* 輸出: 打開(kāi)微信 打開(kāi)Chrome 打開(kāi)Email */傻瓜命令與智能命令
傻瓜命令:命令對(duì)象需要接收者來(lái)執(zhí)行客戶(hù)的請(qǐng)求。智能命令:命令對(duì)象直接實(shí)現(xiàn)請(qǐng)求,不需要接收者,“聰明”的命令對(duì)象。
“傻瓜命令” 與 “智能命令” 的區(qū)別在于是否有 “接收者” 對(duì)象。
// openWechat 是智能命令對(duì)象,并沒(méi)有傳入 receiver 接收對(duì)象 const openWechat = { execute: () => { // 命令對(duì)象直接處理請(qǐng)求 console.log("打開(kāi)微信"); } };
沒(méi)有 “接收者” 的智能命令與策略模式很類(lèi)似。代碼實(shí)現(xiàn)類(lèi)似,區(qū)別在于實(shí)現(xiàn)目標(biāo)不同。
策略模式中實(shí)現(xiàn)的目標(biāo)是一致的,只是實(shí)現(xiàn)算法不同(如目標(biāo):根據(jù)KPI計(jì)算獎(jiǎng)金);
智能命令的解決問(wèn)題更廣,目標(biāo)更具散發(fā)性。(如目標(biāo):計(jì)算獎(jiǎng)金/計(jì)算出勤率等)。
參考文章
《JavaScript 設(shè)計(jì)模式與開(kāi)發(fā)實(shí)踐》
本文首發(fā)Github,期待Star!
https://github.com/ZengLingYong/blog
作者:以樂(lè)之名
本文原創(chuàng),有不當(dāng)?shù)牡胤綒g迎指出。轉(zhuǎn)載請(qǐng)指明出處。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://www.ezyhdfw.cn/yun/105635.html
摘要:裝飾者模式裝飾者模式提供比繼承更有彈性的替代方案。裝飾者用于包裝同接口的對(duì)象,用于通過(guò)重載方法的形式添加新功能,該模式可以在被裝飾者的前面或后面加上自己的行為以達(dá)到特定的目的。簡(jiǎn)單的理解給對(duì)象動(dòng)態(tài)添加職責(zé)的方式稱(chēng)為裝飾著模式。 裝飾者模式 裝飾者模式提供比繼承更有彈性的替代方案。裝飾者用于包裝同接口的對(duì)象,用于通過(guò)重載方法的形式添加新功能,該模式可以在被裝飾者的前面或后面加上自己的行為...
摘要:與門(mén)面模式的聯(lián)系本文要說(shuō)的適配器模式和上一篇門(mén)面模式在思想上有相似之處,所以放在一起說(shuō)。我們以中的一個(gè)為例,說(shuō)說(shuō)實(shí)際應(yīng)用中的適配器模式的使用方法。而如果實(shí)現(xiàn)層的問(wèn)題不大,要解決一部分適配問(wèn)題的話,適配器模式就是很好的選擇了。 與門(mén)面模式的聯(lián)系 本文要說(shuō)的適配器模式和上一篇門(mén)面模式在思想上有相似之處,所以放在一起說(shuō)。它們都對(duì)類(lèi)的接口進(jìn)行了一些改變。門(mén)面模式是把相似的或是完成相關(guān)任務(wù)的接...
摘要:參考鏈接面向?qū)ο缶幊棠P同F(xiàn)在的很多編程語(yǔ)言基本都具有面向?qū)ο蟮乃枷?,比如等等,而面向?qū)ο蟮闹饕枷雽?duì)象,類(lèi),繼承,封裝,多態(tài)比較容易理解,這里就不多多描述了。 前言 在我們的日常日發(fā)和學(xué)習(xí)生活中會(huì)常常遇到一些名詞,比如 命令式編程模型,聲明式編程模型,xxx語(yǔ)言是面向?qū)ο蟮牡鹊?,這個(gè)編程模型到處可見(jiàn),但是始終搞不清是什么?什么語(yǔ)言又是什么編程模型,當(dāng)你新接觸一門(mén)語(yǔ)言的時(shí)候,有些問(wèn)題是需...
閱讀 2348·2021-11-15 11:39
閱讀 1110·2021-09-26 09:55
閱讀 1015·2021-09-04 16:48
閱讀 3006·2021-08-12 13:23
閱讀 993·2021-07-30 15:30
閱讀 2527·2019-08-29 14:16
閱讀 967·2019-08-26 10:15
閱讀 597·2019-08-23 18:40