最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java設(shè)計模式之命令模式

 更新時間:2022年10月11日 09:09:11   作者:tianClassmate  
這篇文章介紹了Java設(shè)計模式之命令模式,文中通過示例代碼介紹的非常詳細。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下

本文通過解決老王經(jīng)常搞錯借書人的問題,來引出行為型模式中的命令模式。為了在案例之上理解的更加透徹,我們需要了解命令模式在源碼中的應(yīng)用。最后指出命令模式的應(yīng)用場景和優(yōu)缺點。

讀者可以拉取完整代碼到本地進行學(xué)習(xí),實現(xiàn)代碼均測試通過后上傳到碼云,本地源碼下載

一、引出問題

老王的書房藏書越來越多,每天來借書的人絡(luò)繹不絕。每天有人借書、還書、老王將A借的書算到B頭上的烏龍事件頻出。老王和小王就商量著手解決這個問題。

小王提議,在老王和借書者之間再增加一個“記錄員”角色,記錄員只管報名字就行了,具體是借什么書由借書者自己決定就好了。

老王說:這能解決部分問題。但在真實的場景下,不可能來一個借書者“記錄員”就跑一趟。而且借書者有時候會借一半臨時有事就不借了。這些問題你也要考慮進去。

老王接著說:你應(yīng)該,在“記錄員”角色中,增加一個隊列,將所有借書者都放到一個隊列中,既有往隊列中放命令的方法,也有從命令中移除的方法,方便“記錄員”請求排隊和“撤銷”。

二、命令模式的概念和應(yīng)用

老王提出來的正是命令模式的“白話文解釋”。我們來看命令模式的官方概念:將一個請求封裝為一個對象,使發(fā)出請求的責(zé)任和執(zhí)行請求的責(zé)任分割開,解耦合。這樣兩者之間通過命令對象進行溝通,這樣方便將命令對象進行存儲、傳遞、調(diào)用、增加與管理。

在命令模式中有三個角色:

抽象命令類(Command)角色: 定義命令的接口,聲明執(zhí)行的方法。

實現(xiàn)者/接收者(Receiver)(老王)角色: 接收者,真正執(zhí)行命令的對象。任何類都可能成為一個接收者,只要它能夠?qū)崿F(xiàn)命令要求實現(xiàn)的相應(yīng)功能。

具體命令(Concrete Command)(記錄員)角色:具體的命令,實現(xiàn)命令接口;通常會持有接收者,并調(diào)用接收者的功能來完成命令要執(zhí)行的操作。

我們基于概念和角色劃分,實現(xiàn)代碼:

抽象命令類:

/**
 * 抽象命令類
 * @author tcy
 * @Date 25-08-2022
 */
public interface AbstractCommand {

    //只需要定義一個統(tǒng)一的執(zhí)行方法
    void execute();
}

具體命令角色(老王):

/**
 * 具體命令
 * @author tcy
 * @Date 25-08-2022
 */
public class ConcreteCommand implements AbstractCommand {

    //持有接受者對象
    private String clent;

    public ConcreteCommand(String clent){
        this.clent = clent;
    }

    @Override
    public void execute() {
        System.out.println("具體執(zhí)行者角色(老王):"+clent+"借書...");

    }
}

接收者(記錄員):

/**
 * 接收者
 * @author tcy
 * @Date 25-08-2022
 */
public class ReceiverCommand {

    //可以持有很多的命令對象
    private ArrayList<AbstractCommand> commands;

    public ReceiverCommand() {
        commands = new ArrayList();
    }

    public void setCommand(AbstractCommand cmd){
        commands.add(cmd);
    }

    public void removeCommand(AbstractCommand cmd){
        commands.remove(cmd);
    }

    // 發(fā)出命令
    public void borrowBookMeaaage() {
        System.out.println("接受者角色(記錄員):有人來借書啦...");
        //通知全部命令
        for (int i = 0; i < commands.size(); i++) {
            AbstractCommand cmd = commands.get(i);
            if (cmd != null) {
                cmd.execute();
            }
        }
    }
}

客戶端(借書者):

/**
 * @author tcy
 * @Date 25-08-2022
 */
public class Client {

    public static void main(String[] args) {

        //創(chuàng)建接收者
        //將訂單和接收者封裝成命令對象
        ConcreteCommand cmd1 = new ConcreteCommand( "A");
        ConcreteCommand cmd2 = new ConcreteCommand( "B");

        //創(chuàng)建具體命令者
        ReceiverCommand invoker = new ReceiverCommand();
        invoker.setCommand(cmd1);
        invoker.setCommand(cmd2);

        //喊一聲有人要借書
        invoker.borrowBookMeaaage();


    }

}

基于命令模式實現(xiàn)的代碼就實現(xiàn)了,但是看懂代碼是一回事,自己能寫出來就是另外一回事了。讀者最好根據(jù)案例重新仿寫一遍。

三、源碼中的應(yīng)用

在源碼中使用命令模式的典型案例就是Jdk多線程章節(jié)中的Runnable ,Runnable 相當(dāng)于命令模式中的抽象命令角色。Runnable 中的 run() 方法就當(dāng)于 execute() 方法。

我們知道,Java中一個類實現(xiàn)Runnable 接口,那么該類就認為是一個線程,就相當(dāng)于命令模式中的具體命令角色。

當(dāng)我們調(diào)用start()方法后,就可以與別的線程強占CPU的資源,在占用CPU的線程中就會執(zhí)行run()方法。CPU的調(diào)度者就相當(dāng)于具體命令角色也即記錄員。Runnable 就完美的實現(xiàn)了用戶自定義線程和CPU的解耦合。

命令模式在Runnable 中的應(yīng)用應(yīng)該很好理解。

四、總結(jié)

優(yōu)點很明顯,解耦了命令請求與實現(xiàn),很容易的可以增加新命令,支持命令隊列。

但是,這樣會不可避免的使具體命令類過多,增加了理解上的困難。

設(shè)計模式學(xué)到這種程度,我們就會發(fā)現(xiàn)設(shè)計模式不是一種單一的技術(shù),而是各種技術(shù)的綜合體。

我們在學(xué)習(xí)設(shè)計模式的時候一定不要僅局限于一種模式,而是站在一定的高度去整體衡量哪種設(shè)計模式才是最優(yōu)的。

有時候我們會發(fā)現(xiàn),使用設(shè)計模式會讓我們的代碼變得更加的復(fù)雜,但以自己目前的開發(fā)經(jīng)驗又不能確定是否采用設(shè)計模式是一個好的選擇。

歸根結(jié)低,還是我們對設(shè)計模式掌握的不夠熟練,這就需要我們繼續(xù)深入學(xué)習(xí)設(shè)計模式,當(dāng)我的學(xué)完再回頭看這些問題,就很自然的迎刃而解了。

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,謝謝大家對腳本之家的支持。如果你想了解更多相關(guān)內(nèi)容請查看下面相關(guān)鏈接

相關(guān)文章

  • SpringBoot實戰(zhàn)之SSL配置詳解

    SpringBoot實戰(zhàn)之SSL配置詳解

    今天小編就為大家分享一篇關(guān)于SpringBoot實戰(zhàn)之SSL配置詳解,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-02-02
  • 如何解決EasyExcel導(dǎo)出文件LocalDateTime報錯問題

    如何解決EasyExcel導(dǎo)出文件LocalDateTime報錯問題

    這篇文章主要介紹了如何解決EasyExcel導(dǎo)出文件LocalDateTime報錯問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-06-06
  • 使用Spring Cloud Feign遠程調(diào)用的方法示例

    使用Spring Cloud Feign遠程調(diào)用的方法示例

    這篇文章主要介紹了使用Spring Cloud Feign遠程調(diào)用的方法示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-09-09
  • Spring JPA find單表查詢方法示例詳解

    Spring JPA find單表查詢方法示例詳解

    這篇文章主要為大家介紹了Spring JPA find單表查詢方法示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • Java面向?qū)ο笾畠?nèi)部類案例講解

    Java面向?qū)ο笾畠?nèi)部類案例講解

    這篇文章主要介紹了Java面向?qū)ο笾畠?nèi)部類案例講解,本篇文章通過簡要的案例,講解了該項技術(shù)的了解與使用,以下就是詳細內(nèi)容,需要的朋友可以參考下
    2021-08-08
  • 使用java代碼實現(xiàn)保留小數(shù)點的位數(shù)

    使用java代碼實現(xiàn)保留小數(shù)點的位數(shù)

    因為個人應(yīng)用的需要,所以就寫個簡單點的了。希望大家都給給建議,共同學(xué)習(xí)。需要的朋友也可以參考下
    2013-07-07
  • springboot結(jié)合全局異常處理實現(xiàn)登錄注冊驗證

    springboot結(jié)合全局異常處理實現(xiàn)登錄注冊驗證

    這篇文章主要介紹了springboot結(jié)合全局異常處理實現(xiàn)登錄注冊驗證,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2019-05-05
  • Java中Exception和Error的區(qū)別詳解

    Java中Exception和Error的區(qū)別詳解

    在 Java 開發(fā)面試中,Exception 和 Error 的區(qū)別是一個經(jīng)典問題,這個問題不僅考察我們對 Java 異常處理機制的理解,還考察我們在實際開發(fā)中如何處理異常的能力,所以本文主要給大家介紹一下Java中Exception和Error的區(qū)別,需要的朋友可以參考下
    2025-04-04
  • SpringBoot實現(xiàn)分頁功能

    SpringBoot實現(xiàn)分頁功能

    這篇文章主要為大家詳細介紹了SpringBoot實現(xiàn)分頁功能,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • Spring運行環(huán)境Environment的解析

    Spring運行環(huán)境Environment的解析

    本文主要介紹了Spring運行環(huán)境Environment的解析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-08-08

最新評論

梁山县| 衡阳县| 英山县| 若尔盖县| 彰化县| 新源县| 防城港市| 临猗县| 浦东新区| 富源县| 卢氏县| 专栏| 西乌珠穆沁旗| 阿合奇县| 浙江省| 丹阳市| 吉安县| 阿坝县| 平安县| 额尔古纳市| 周口市| 神农架林区| 麦盖提县| 铁力市| 金湖县| 滨海县| 芜湖县| 绥滨县| 财经| 犍为县| 金阳县| 丰都县| 扬州市| 长顺县| 临安市| 德江县| 普兰店市| 麻江县| 德惠市| 桑植县| 泊头市|