日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

设计模式:命令模式(Command)

發(fā)布時間:2024/4/11 asp.net 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式:命令模式(Command) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

歡迎支持筆者新作:《深入理解Kafka:核心設(shè)計與實踐原理》和《RabbitMQ實戰(zhàn)指南》,同時歡迎關(guān)注筆者的微信公眾號:朱小廝的博客。


歡迎跳轉(zhuǎn)到本文的原文鏈接:https://honeypps.com/design_pattern/command/

?將一個請求封裝為一個對象,從而使你可用不同的請求對客戶進行參數(shù)化;對請求排隊或記錄請求日志,以支持可撤銷的操作。

命令模式的角色

  • 客戶端角色(Client):創(chuàng)建一個具體命令(ConcreteCommand)對象并確定其接收者。
  • 命令角色(Command):聲明一個給所有命令類的抽象接口。
  • 具體命令角色(ConcreteCommand):定義一個接收者和行為之間的弱耦合;實現(xiàn)execute()方法,負(fù)責(zé)調(diào)用接收者的相應(yīng)操作。execute()方法叫做執(zhí)行方法。
  • 請求者角色(Invoker):負(fù)責(zé)調(diào)用命令對象執(zhí)行請求,相關(guān)的方法叫做行動方法。
  • 接收者角色(Receiver):負(fù)責(zé)具體實施和執(zhí)行一個請求。任何一個類都可以稱為接收者,實施和執(zhí)行請求的方法叫做行動方法。
  • 舉個簡單例子(錄音機有播音Play,倒帶Rewind和停止Stop功能)
    1 接收者角色

    public class AudioPlayer {public void play(){System.out.println("Play");}public void rewind(){System.out.println("Rewind");}public void stop(){System.out.println("Stop");} }

    2 抽象命令角色

    public interface Command {public void execute(); }

    3 具體命令角色

    public class PlayCommand implements Command {private AudioPlayer myAudio;public PlayCommand(AudioPlayer audioPlayer){this.myAudio = audioPlayer;}@Overridepublic void execute(){myAudio.play();} } public class RewindCommand implements Command {private AudioPlayer myAudio;public RewindCommand(AudioPlayer audioPlayer){this.myAudio = audioPlayer;}@Overridepublic void execute(){this.myAudio.rewind();} } public class StopCommand implements Command {private AudioPlayer myAudio;public StopCommand(AudioPlayer audioPlayer){this.myAudio = audioPlayer;}@Overridepublic void execute(){this.myAudio.stop();} }

    4 請求這角色(由按鍵扮演)

    public class Keypad {private Command playCommand;private Command rewindCommand;private Command stopCommand;public void setPlayCommand(Command playCommand){this.playCommand = playCommand;}public void setRewindCommand(Command rewindCommand){this.rewindCommand = rewindCommand;}public void setStopCommand(Command stopCommand){this.stopCommand = stopCommand;}public void play(){playCommand.execute();}public void rewind(){rewindCommand.execute();}public void stop(){stopCommand.execute();} }

    5 客戶端角色

    AudioPlayer audioPlayer = new AudioPlayer();Command playCommand = new PlayCommand(audioPlayer);Command rewindCommand = new RewindCommand(audioPlayer);Command stopCommand = new StopCommand(audioPlayer);Keypad keypad = new Keypad();keypad.setPlayCommand(playCommand);keypad.setRewindCommand(rewindCommand);keypad.setStopCommand(stopCommand);keypad.play();keypad.rewind();keypad.stop();

    輸出:

    Play Rewind Stop

    ##宏命令
    ?所謂的宏命令簡單點說就是包含多個命令的命令,是一個命令的組合。
    ?修改上面的案例,當(dāng)客戶端需要一個記錄的工,可以把一個一個命令記錄下來,再在任何需要的時候重新把這些記錄下來的命令一次執(zhí)行,這就是所謂的宏命令功能。
    1 系統(tǒng)需要一個代表宏命令的接口,以定義出具體宏命令所需要的接口

    public interface MacroCommand extends Command {public void add(Command cmd);public void remove(Command cmd); }

    2 具體的宏命令MarcoAudioCommand類負(fù)責(zé)把個別的命令合成宏命令

    public class MacroAudioCommand implements MacroCommand {private List<Command> commandList = new ArrayList<Command>();@Overridepublic void execute(){for(Command cmd: commandList){cmd.execute();}}@Overridepublic void add(Command cmd){commandList.add(cmd);}@Overridepublic void remove(Command cmd){commandList.remove(cmd);} }

    3 客戶端

    AudioPlayer audioPlayer = new AudioPlayer();Command playCommand = new PlayCommand(audioPlayer);Command rewindCommand = new RewindCommand(audioPlayer);Command stopCommand = new StopCommand(audioPlayer);MacroCommand marco = new MacroAudioCommand();marco.add(playCommand);marco.add(rewindCommand);marco.add(stopCommand);marco.execute();

    適用場景
    ?在下面的情況下應(yīng)當(dāng)考慮應(yīng)用命令模式:

  • 使用命令模式作為CallBack在面向?qū)ο笙到y(tǒng)中的替代。CallBack講的便是先將一個函數(shù)等級上,然后在以后調(diào)用此函數(shù)。
  • 需要在不同的時間指定請求、將請求排隊。一個命令對象和原先的請求發(fā)出者可以有不同的生命期。換言之,原先的請求發(fā)出者可能已經(jīng)不存在了,而名對象本身仍然是活動的。這時命令的接受者可以是在本地,也可以在網(wǎng)絡(luò)的另外一個地址。命令對象可以在串行化之后送到一臺機器上去。
  • 系統(tǒng)需要支持命令的撤銷(undo)。命令對象可以把狀態(tài)存儲起來,等到客戶端需要撤銷命令所產(chǎn)生的效果時,可以調(diào)用undo()方法,把命令所產(chǎn)生的效果撤銷掉。命令對象還可以提供redo()方法,以供客戶端在需要時,再重新實施命令效果。
  • 日志請求(系統(tǒng)恢復(fù)):如果一個系統(tǒng)要將系統(tǒng)中所有的數(shù)據(jù)更新到日志里,以便在系統(tǒng)崩潰時,可以根據(jù)日志里讀回所有的數(shù)據(jù)更新命令,重新調(diào)用Execute()方法一條一條執(zhí)行這些命令,從而恢復(fù)系統(tǒng)在崩潰前所做的數(shù)據(jù)更新。
  • 工作隊列,線程池,日程安排。
  • 優(yōu)缺點
    優(yōu)點:

  • 更松散的耦合:命令模式使得發(fā)起命令的對象(客戶端)和具體實現(xiàn)命令的對象(接收者)完全解耦,也就是說發(fā)起命令的對象完全不知道具體實現(xiàn)對象是誰,也不知道該如何實現(xiàn)。
  • 更動態(tài)的控制:命令模式把請求封裝起來,可以動態(tài)地對它進行參數(shù)化、隊列化和日志化,從而使得系統(tǒng)更靈活。
  • 很自然的復(fù)合命令:命令模式中的命令對象能夠很容易地組合成復(fù)合命令,也就是宏命令,從而使系統(tǒng)操作更簡單,功能更強大。
  • 更好的擴展性:由于發(fā)起命令的對象和具體的實現(xiàn)完全解耦,因此擴展新的命令就很容易,只需要實現(xiàn)新的命令對象,然后在裝配的時候,把具體的實現(xiàn)對象設(shè)置到命令對象中,然后就可以使得這個命令對象,已有的實現(xiàn)完全不用變化。
  • 缺點:

  • 使用命令模式可能會導(dǎo)致某些系統(tǒng)有過多的具體命令類。因為針對每一個命令都需要設(shè)計一個具體命令類,因此某些系統(tǒng)可能需要大量具體命令類,這將影響命令模式的使用。
  • JDK中的命令模式
    java.lang.Runnable
    javax.swing.Action


    參考資料

  • 23種設(shè)計模式
  • 細(xì)數(shù)JDK里的設(shè)計模式
  • 《JAVA與模式》之命令模式
  • 歡迎跳轉(zhuǎn)到本文的原文鏈接:https://honeypps.com/design_pattern/command/

    歡迎支持筆者新作:《深入理解Kafka:核心設(shè)計與實踐原理》和《RabbitMQ實戰(zhàn)指南》,同時歡迎關(guān)注筆者的微信公眾號:朱小廝的博客。


    總結(jié)

    以上是生活随笔為你收集整理的设计模式:命令模式(Command)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。