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