摘要:命令模式屬于行為型模式的一種,又稱為行動(dòng)模式或交易模式。結(jié)構(gòu)圖模式結(jié)構(gòu)抽象命令類聲明了用于執(zhí)行請(qǐng)求的的等方法具體命令類抽象命令類的子類,對(duì)應(yīng)具體的接收者對(duì)象,將接收者對(duì)象的動(dòng)作綁定其中。
概述命令模式(Command Pattern)屬于行為型模式的一種,又稱為行動(dòng)(Action)模式或交易(Transaction)模式。將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象,從而達(dá)到用不同的請(qǐng)求對(duì)客戶進(jìn)行參數(shù)化,對(duì)于排隊(duì)請(qǐng)求或請(qǐng)求日志記錄,可以提供命令的撤銷和恢復(fù)功能。
命令模式:對(duì)命令的封裝,把發(fā)送命令和執(zhí)行命令的責(zé)任分割開,分別委派給不同的對(duì)象,每一個(gè)命令都是一個(gè)操作,允許請(qǐng)求方與接收方獨(dú)立開來,使之請(qǐng)求方不必清楚接收方的接口,更不必知道請(qǐng)求是怎么被接收,以及操作是否被執(zhí)行、何時(shí)被執(zhí)行,以及是怎么被執(zhí)行的。
UML結(jié)構(gòu)圖
模式結(jié)構(gòu)
Command(抽象命令類): 聲明了用于執(zhí)行請(qǐng)求的的exceute()等方法
ConcreteCommand(具體命令類): 抽象命令類的子類,對(duì)應(yīng)具體的接收者對(duì)象,將接收者對(duì)象的動(dòng)作綁定其中。在實(shí)現(xiàn)execute()方
法時(shí),將調(diào)用接收者對(duì)象的相關(guān)操作(Action)。
Invoker(調(diào)用者): 調(diào)用命令對(duì)象執(zhí)行請(qǐng)求,相關(guān)的方法叫做行動(dòng)方法。
Receiver(接收者): 負(fù)責(zé)具體實(shí)施和執(zhí)行一個(gè)請(qǐng)求。任何一個(gè)類都可以成為接收者,實(shí)施和執(zhí)行請(qǐng)求的方法叫做行動(dòng)方法。
案例博主比較喜歡聽歌,這里就以MusicPlayer(音樂播放器)為案例,一般播放器中都有播放(play),跳過(skip),停止(stop)等功能,是一種比較典型的命令模式
UML圖如下:
1.定義Command(抽象命令類),只有一個(gè)execute()用來執(zhí)行命令
interface Command { void execute(); }
2.創(chuàng)建不同指令的ConcreteCommand(具體命令類)
class PlayCommand implements Command { private MusicPlayer musicPlayer; public PlayCommand(MusicPlayer musicPlayer) { this.musicPlayer = musicPlayer; } @Override public void execute() { musicPlayer.play(); } } class SkipCommand implements Command { private MusicPlayer musicPlayer; public SkipCommand(MusicPlayer musicPlayer) { this.musicPlayer = musicPlayer; } @Override public void execute() { musicPlayer.skip(); } } class StopCommand implements Command { private MusicPlayer musicPlayer; public StopCommand(MusicPlayer musicPlayer) { this.musicPlayer = musicPlayer; } @Override public void execute() { musicPlayer.stop(); } }
3.MusicInvoker(調(diào)用者),接收客戶端發(fā)送過來的指令
class MusicInvoker { private Command playCommand; private Command skipCommand; private Command stopCommand; public void setPlayCommand(Command playCommand) { this.playCommand = playCommand; } public void setSkipCommand(Command skipCommand) { this.skipCommand = skipCommand; } public void setStopCommand(Command stopCommand) { this.stopCommand = stopCommand; } public void play() { playCommand.execute(); } public void skip() { skipCommand.execute(); } public void stop() { stopCommand.execute(); } }
4.MusicPlayer(接收者),執(zhí)行接收到的指令
class MusicPlayer { public void play() { System.out.println("播放..."); } public void skip() { System.out.println("跳過..."); } public void stop() { System.out.println("停止..."); } }
5.測(cè)試類MusicPlayerClient
public class MusicPlayerClient { public static void main(String[] args) { // 創(chuàng)建 Receiver(接收者) MusicPlayer musicPlayer = new MusicPlayer(); // Command(抽象命令類) Command playCommand = new PlayCommand(musicPlayer); Command skipCommand = new SkipCommand(musicPlayer); Command stopCommand = new StopCommand(musicPlayer); // 創(chuàng)建 Invoker(調(diào)用者) MusicInvoker invoker = new MusicInvoker(); invoker.setPlayCommand(playCommand); invoker.setSkipCommand(skipCommand); invoker.setStopCommand(stopCommand); // 測(cè)試 invoker.play(); invoker.skip(); invoker.stop(); invoker.play(); invoker.stop(); } }
6.運(yùn)行結(jié)果
宏命令宏命令: 又稱為組合命令,組合多個(gè)命令,它是命令模式和組合模式聯(lián)用的產(chǎn)物;
假設(shè)MusicPlayer(音樂播放器)有一個(gè)記錄功能,可以把每一個(gè)命令記錄下來,在需要的時(shí)候又可以將歷史記錄的命令在執(zhí)行一遍,這就是所謂的宏命令集功能。
UML圖如下:
1.定義MacroCommand(宏命令類),繼承基礎(chǔ)Command(命令類)
interface MacroCommand extends Command { void add(Command command); void remove(Command command); }
2.創(chuàng)建MacroMusicCommand實(shí)現(xiàn)MacroCommand
class MacroMusicCommand implements MacroCommand { private static final ListCOMMANDS = new ArrayList<>(); @Override public void execute() { System.out.println("==========回放開始=========="); COMMANDS.forEach(Command::execute); System.out.println("==========回放結(jié)束=========="); } @Override public void add(Command command) { COMMANDS.add(command); } @Override public void remove(Command command) { COMMANDS.remove(command); } }
3.測(cè)試類
public class MusicPlayerClient { public static void main(String[] args) { // 創(chuàng)建 Receiver(接收者) MusicPlayer musicPlayer = new MusicPlayer(); // Command(抽象命令類) Command playCommand = new PlayCommand(musicPlayer); Command skipCommand = new SkipCommand(musicPlayer); Command stopCommand = new StopCommand(musicPlayer); // 創(chuàng)建 Invoker(調(diào)用者) MacroCommand macroCommand = new MacroMusicCommand(); macroCommand.add(playCommand); macroCommand.add(skipCommand); macroCommand.add(stopCommand); // 測(cè)試 macroCommand.execute(); } }
4.運(yùn)行結(jié)果
JDK中應(yīng)用我們平時(shí)使用的java.lang.Runnable就是命令模式的經(jīng)典應(yīng)用
// 命令類 與 具體命令實(shí)現(xiàn)類 Runnable runnable = new Runnable() { @Override public void run() { System.out.println("關(guān)注 battcn 公眾號(hào)即可免費(fèi)領(lǐng)取視頻"); } }; // Invoker(調(diào)用者) 接收命令 Thread thread = new Thread(runnable); // 調(diào)用 start 命令 thread.start(); // JDK8 簡(jiǎn)化寫法 new Thread(()->System.out.println("關(guān)注 battcn 公眾號(hào)即可免費(fèi)領(lǐng)取視頻")).start();總結(jié)
優(yōu)點(diǎn)
將行為調(diào)用者和各種行為分隔開,降低程序的耦合,便于程序擴(kuò)展;
將行為的具體實(shí)現(xiàn)封裝起來,客戶端無需關(guān)心行為的具體實(shí)現(xiàn);
為多種行為提供統(tǒng)一的調(diào)用入口,便于程序?qū)π袨榈墓芾砗涂刂疲?/p>
缺點(diǎn)
使用命令模式,不論命令簡(jiǎn)單還是復(fù)雜,都需要寫一個(gè)命令類來封裝,濫用命令模式會(huì)導(dǎo)致系統(tǒng)出現(xiàn)過多的具體命令類;
適用場(chǎng)景
希望將行為請(qǐng)求者和行為實(shí)現(xiàn)者解耦,不直接打交道;
希望分離掉行為請(qǐng)求者一部分的責(zé)任,行為請(qǐng)求者只需要將命令發(fā)給調(diào)用者,不再主動(dòng)的去讓行為實(shí)現(xiàn)者產(chǎn)生行為,符合單一職責(zé)原則;
希望可以控制執(zhí)行的命令列表,方便記錄,撤銷/重做以及事務(wù)等功能;
希望可以將請(qǐng)求組合使用,即支持宏命令;
說點(diǎn)什么全文代碼:https://gitee.com/battcn/design-pattern/tree/master/Chapter12/battcn-command
個(gè)人QQ:1837307557
battcn開源群(適合新手):391619659
微信公眾號(hào):battcn(歡迎調(diào)戲)
福利關(guān)注公眾號(hào):battcn,回復(fù)springboot即可獲得
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/70657.html
摘要:備忘錄模式常常與命令模式和迭代子模式一同使用。自述歷史所謂自述歷史模式實(shí)際上就是備忘錄模式的一個(gè)變種。在備忘錄模式中,發(fā)起人角色負(fù)責(zé)人角色和備忘錄角色都是獨(dú)立的角色。 備忘錄模式(Memento Pattern)屬于行為型模式的一種,在不破壞封裝特性的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在該對(duì)象之外保存這個(gè)狀態(tài)。這樣就可以將該對(duì)象恢復(fù)到原先保存的狀態(tài)。 概述 備忘錄模式又叫做快照模式(...
摘要:抽象工廠模式提供了創(chuàng)建一系列相互依賴對(duì)象的接口,無需指定具體類抽象工廠模式是圍繞著一個(gè)超級(jí)工廠工作,創(chuàng)造其它的工廠類,也被稱為工廠的工廠,這種類型的設(shè)計(jì)模式是創(chuàng)造性的模式,因?yàn)檫@種模式提供了創(chuàng)建對(duì)象的最佳方法之一。 工廠模式是JAVA中最常用的設(shè)計(jì)模式之一,使用工廠模式后,創(chuàng)建對(duì)象的時(shí)候不在將創(chuàng)建邏輯暴露給客戶端,而是通過實(shí)現(xiàn)接口的方式創(chuàng)建對(duì)象,這種設(shè)計(jì)模式也是對(duì)象實(shí)例化的最佳方式。 ...
摘要:適配器是將接口轉(zhuǎn)換為不同接口,而外觀模式是提供一個(gè)統(tǒng)一的接口來簡(jiǎn)化接口。 外觀模式(Facade Pattern)屬于結(jié)構(gòu)型模式的一種,為子系統(tǒng)中的一組接口提供一個(gè)統(tǒng)一的入口,它通過引入一個(gè)外觀角色來簡(jiǎn)化客戶端與子系統(tǒng)之間的交互... 概述 外觀模式是一種使用頻率非常高的結(jié)構(gòu)型設(shè)計(jì)模式,當(dāng)你要為一個(gè)復(fù)雜子系統(tǒng)提供一個(gè)簡(jiǎn)單接口時(shí)。子系統(tǒng)往往因?yàn)椴粩嘌莼兊迷絹碓綇?fù)雜。大多數(shù)模式使用時(shí)...
摘要:構(gòu)造函數(shù)參數(shù)太多錯(cuò)誤的對(duì)象狀態(tài)使用模式在我們的示例中,改造下召喚師類齊天大圣孫悟空上單基石天賦戰(zhàn)爭(zhēng)雷霆瘟疫之源圖奇下路基石天賦戰(zhàn)陣熱誠皎月女神戴安娜中單建造者模式讓我們寫的代碼更具可讀性,可理解為建立復(fù)雜的物體。 建造者模式(Builder Pattern)屬于創(chuàng)建型模式的一種,將多個(gè)簡(jiǎn)單對(duì)象構(gòu)建成一個(gè)復(fù)雜的對(duì)象,構(gòu)建過程抽象化,不同實(shí)現(xiàn)方法可以構(gòu)造出不同表現(xiàn)(屬性)的對(duì)象,還提供了一...
摘要:策略模式使得算法可以在不影響到客戶端的情況下發(fā)生變化。下面就以一個(gè)示意性的實(shí)現(xiàn)講解策略模式實(shí)例的結(jié)構(gòu)。抽象策略角色這是一個(gè)抽象角色,通常由一個(gè)接口或抽象類實(shí)現(xiàn)。優(yōu)點(diǎn)策略模式提供了管理相關(guān)的算法族的辦法。 策略模式(Strategy Pattern)屬于對(duì)象行為型模式的一種,其用意是針對(duì)一組算法,將每一個(gè)算法封裝到具有共同接口的獨(dú)立的類中,從而使得它們可以相互替換。策略模式使得算法可以...
閱讀 2491·2021-10-19 11:45
閱讀 2477·2021-09-30 09:56
閱讀 1441·2021-09-30 09:47
閱讀 597·2019-08-30 15:53
閱讀 1840·2019-08-30 15:44
閱讀 587·2019-08-30 12:52
閱讀 1089·2019-08-30 11:16
閱讀 1613·2019-08-29 16:36