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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

命令模式的两种不同实现

發布時間:2023/12/3 编程问答 15 豆豆
生活随笔 收集整理的這篇文章主要介紹了 命令模式的两种不同实现 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉載自?命令模式(Command)的兩種不同實現

命令模式(Command:將一個請求封裝成一個對象,使得你用不同的請求把客戶端參數化,對請求排隊或者記錄請求日志,可以提供命令的撤銷和恢復功能。 命令模式,顧名思義來理解即可,就是客戶端發布一個命令(也就是“請求”),而這個命令是已經被封裝成一個對象的。即這個命令對象的內部可能已經指定了該命令具體被誰負責執行。就像開發經理從客戶那邊獲取對方的需求(命令),客戶在描述具體的需求可以決定是否明確指出該需求的執行方。 命令模式的通用類圖如下:?

上圖中,Invoker?類就相當于開發經理,ConcreteCommand?類是具體的命令,它繼承自抽象命令類?Command?類,該抽象類中定義了每個命令被執行的方法?execute()?。Receiver?抽象類定義了對每一個具體的命令的執行方法?action()?,一旦接收到命令則立即行動。這里應該注意的是,每個具體的命令類都必須指定該命令的接收者,否則這命令發布了也沒相應的人來完成,那就沒戲了。 具體代碼實現如下: 命令接收者相關類:
  • //抽象接收者,定義了每個接收者應該完成的業務邏輯 ?
  • abstract?class?AbstractReceiver?{ ?
  • ????public?abstract?void?doJob(); ?
  • } ?
  • ?
  • //?具體接收者01,實現自己真正的業務邏輯 ?
  • class?Receiver01?extends?AbstractReceiver?{ ?
  • ????public?void?doJob()?{ ?
  • ????????System.out.println("接收者01?完成工作?...\n"); ?
  • ????} ?
  • } ?
  • ?
  • //?具體接收者02,實現自己真正的業務邏輯 ?
  • class?Receiver02?extends?AbstractReceiver?{ ?
  • ????public?void?doJob()?{ ?
  • ????????System.out.println("接收者02?完成工作?...\n"); ?
  • ????} ?
  • }?
  • 命令類:
  • //?抽象命令類,定義了每個具體命令被執行的入口方法execute() ?
  • abstract?class?AbstractCommand?{ ?
  • ????public?abstract?void?execute(); ?
  • } ?
  • ?
  • //?具體命令類01,通過構造函數的參數決定了該命令由哪個接收者執行 ?
  • class?Command01?extends?AbstsractCommand?{ ?
  • ????private?AbstractReceiver?receiver?=?null; ?
  • ?
  • ????public?Command01(AbstractReceiver?receiver)?{ ?
  • ????????this.receiver?=?receiver; ?
  • ????} ?
  • ?
  • ????public?void?execute()?{ ?
  • ??????????????System.out.println("命令01?被發布?..."); ?
  • ????????this.receiver.doJob(); ?
  • ????} ?
  • } ?
  • ?
  • //?具體命令類02,通過構造函數的參數決定了該命令由哪個接收者執行 ?
  • class?Command02?extends?AbstractCommand?{ ?
  • ????private?AbstractReceiver?receiver?=?null; ?
  • ?
  • ????public?Command02(AbstractReceiver?receiver)?{ ?
  • ????????this.receiver?=?receiver; ?
  • ????} ?
  • ?
  • ????public?void?execute()?{ ?
  • ??????????????System.out.println("命令02?被發布?..."); ?
  • ????????this.receiver.doJob(); ?
  • ????} ?
  • }?
  • 調用者類:
  • //?調用者,負責將具體的命令傳送給具體的接收者 ?
  • class?Invoker?{ ?
  • ????private?AbstractCommand?command?=?null; ?
  • ?
  • ????public?void?setCommand(AbstractCommand?command)?{ ?
  • ????????this.command?=?command; ?
  • ????} ?
  • ?
  • ????public?void?action()?{ ?
  • ????????this.command.execute(); ?
  • ????} ?
  • }?
  • 測試類:
  • //測試類 ?
  • public?class?Client?{ ?
  • ????public?static?void?main(String[]?args)?{ ?
  • ????????//?創建調用者 ?
  • ????????Invoker?invoker?=?new?Invoker(); ?
  • ?
  • ????????//?創建一個具體命令,并指定該命令被執行的具體接收者 ?
  • ????????AbstractCommand?command01?=?new?Command01(new?Receiver01()); ?
  • ?
  • ????????//?給調用者發布一個具體命令 ?
  • ????????invoker.setCommand(command01); ?
  • ?
  • ????????//?調用者執行命令,其實是將其傳送給具體的接收者并讓其真正執行 ?
  • ????????invoker.action(); ?
  • ???????? ?
  • ????????AbstractCommand?command02?=?new?Command01(new?Receiver02()); ?
  • ????????invoker.setCommand(command02); ?
  • ????????invoker.action(); ?
  • ????} ?
  • }?
  • 測試結果:
    命令01?被發布?...接收者01?完成工作?...命令02?被發布?...接收者02?完成工作?...
    如上面測試中輸出的結果,我們知道在客戶端中每次聲明并創建一個具體的命令對象時總要顯式地將其指定給某一具體的接收者(也就是命令的最終執行者),這似乎不太靈活,在現實中有些命令的發布也確實不是預先就指定了該命令的接收者的。 我們可以修改一下類圖,使得客戶端在有必要的時候才顯式地指明命令的接收者,如下:

    較之第一個通用類圖,這里的客戶?Client?類不直接與接收者?Receiver?類相關,而僅僅與調用者?Invoker?類有聯系,客戶發布下來的一個命令或者請求,只需要到了調用者Invoker?這里就停止了,具體怎么實現,不必對客戶公開,由調用者分配即可。這里的?Command?抽象類將子類中指定具體接收者的構造函數的邏輯提取出來,由具體子類提供通過調用父類構造函數的無參、有參構造函數來實現。主要修改的是命令相關的類。? 具體邏輯請看下面的代碼實現: 命令類:
  • /* ?
  • ?*?抽象命令類,使用構造函數的傳入參數預先內定具體接收者,?若想使用其他接收者,可在子類的構造函數中傳入 ?
  • ?*/?
  • abstract?class?AbstractCommand?{ ?
  • ????protected?AbstractReceiver?receiver?=?null; ?
  • ?
  • ????public?AbstractCommand(AbstractReceiver?receiver)?{ ?
  • ????????this.receiver?=?receiver; ?
  • ????} ?
  • ?
  • ????public?abstract?void?execute(); ?
  • } ?
  • ?
  • //?具體命令類01,提供無參、有參兩種構造函數 ?
  • class?Command01?extends?AbstractCommand?{ ?
  • ?
  • ????//?使用無參構造函數來默認使用的具體接收者 ?
  • ????public?Command01()?{ ?
  • ????????super(new?Receiver01()); ?
  • ????} ?
  • ?
  • ????//?使用有參構造函數來指定具體的接收者 ?
  • ????public?Command01(AbstractReceiver?receiver)?{ ?
  • ????????super(receiver); ?
  • ????} ?
  • ?
  • ????public?void?execute()?{ ?
  • ??????????????System.out.println("命令01?被發布?...") ?
  • ????????this.receiver.doJob(); ?
  • ????} ?
  • } ?
  • ?
  • //?具體命令類02,提供無參、有參兩種構造函數 ?
  • class?Command02?extends?AbstractCommand?{ ?
  • ?
  • ????//?使用無參構造函數來默認使用的具體接收者 ?
  • ????public?Command02()?{ ?
  • ????????super(new?Receiver02()); ?
  • ????} ?
  • ?
  • ????//?使用有參構造函數來指定具體的接收者 ?
  • ????public?Command02(AbstractReceiver?receiver)?{ ?
  • ????????super(receiver); ?
  • ????} ?
  • ?
  • ????public?void?execute()?{ ?
  • ??????????????System.out.println("命令02?被發布?...") ?
  • ????????this.receiver.doJob(); ?
  • ????} ?
  • }?
  • 修改后的測試類:
  • //?測試類 ?
  • public?class?Client?{ ?
  • ????public?static?void?main(String[]?args)?{ ?
  • ????????//?創建調用者 ?
  • ????????Invoker?invoker?=?new?Invoker(); ?
  • ?
  • ????????//?創建一個具體命令,并指定該命令被執行的具體接收者 ?
  • //??????AbstractCommand?command01?=?new?Command01(new?Receiver01()); ?
  • ????????AbstractCommand?command01?=?new?Command01(); ?
  • ?
  • ????????//?給調用者發布一個具體命令 ?
  • ????????invoker.setCommand(command01); ?
  • ?
  • ????????//?調用者執行命令,其實是將其傳送給具體的接收者并讓其真正執行 ?
  • ????????invoker.action(); ?
  • ???????? ?
  • //??????AbstractCommand?command02?=?new?Command01(receiver02); ?
  • ????????AbstractCommand?command02?=?new?Command02(); ?
  • ????????invoker.setCommand(command02); ?
  • ????????invoker.action(); ?
  • ???????? ?
  • ????????System.out.println("\n設置命令01由接收者02執行..."); ?
  • ????????command01?=?new?Command01(new?Receiver02()); ?
  • ????????invoker.setCommand(command01); ?
  • ????????invoker.action(); ?
  • ????} ?
  • }?
  • 測試結果:
    命令01?被發布?...接收者01?完成工作?...命令02?被發布?...接收者02?完成工作?...設置命令01由接收者02執行...命令01?被發布?...接收者02?完成工作?...

    此時在客戶端中,我們不指明一個命令的具體接收者(執行者)也同樣可以達到第一種實現方法中的效果。此外,客戶也可以顯式指出具體接收者,就像上面那樣。

    命令模式的優點: 1、?調用者與接收者沒有任何的依賴關系,它們時通過具體的命令的存在而存在的; 2、?若有多個具體命令,只要擴展?Command?的子類即可,同樣地具體接收者也可以相對應地進行擴展; 命令模式的缺點:其實上面優點中第2點在一定場景中也會變成缺點。如果具體的命令有很多個,那么子類就必然會暴增、膨脹。 但是,上面的具體代碼實現中這種設計似乎也不太樂觀,原因是每一個具體的命令都是由一個具體的接收者來執行的,在多交互的場景中這顯然是太理想化的。于是,我想到了中介者模式(Mediator)中最主要的?Mediator?類中預先地注冊了業務中需要交互的同事類的對象,接下來每一次交互邏輯都交給?Mediator?來“暗箱”操作。 根據上一段的想法,我們可以在抽象命令?Command?類中預先注冊一定數量的具體接收者,那么具體命令中就可以決定是否要在多個接收者中進行協作完成了,這種協作的代碼邏輯則應該寫在覆蓋父類的execute()?方法中,而在?execute()?方法中又可以運用模板方法模式(Template?Method)進行設計。

    總結

    以上是生活随笔為你收集整理的命令模式的两种不同实现的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。