再說設計模式-命令模式

定義

命令模式是一個高內(nèi)聚的模式,其定義如下:

Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.
將一個請求封裝成一個對象,從而讓你使用不同的請求把客戶端參數(shù)化,對請求排隊或者記錄請求日志,可以提供命令的撤銷和恢復功能。

命令模式的通用類圖為:


命令模式的通用類圖

在該類圖中,我們看到三個角色:

  • Receive接收者角色
    該角色就是干活的角色,命令傳遞到這里被執(zhí)行;
  • Command命令角色
    需要執(zhí)行的所有命令都在這里聲明;
  • Invoker調用者角色
    接收到命令,并執(zhí)行命令。

命令模式比較簡單,但是在項目中非常頻繁地使用,因為它的封裝性非常好,把請求方(Invoker)和執(zhí)行方(Receiver)分開了,擴展性也有很好的保障,能用代碼比較簡單。

通用Receiver類

public abstract class Receiver {
  // 抽象接收者, 定義每個接收者者必須完成的業(yè)務
  public abstract void doSomething();
}

具體的Receiver類

public class ConcreteReceiver1 extends Receiver {
  public void doSomething() {
    // do something
  }
}

public class ConcreteReceiver2 extends Receiver {
  public void doSomething() {
    // do something
  }
}

接收者可以是N個,這要依賴業(yè)務的具體定義。命令角色是命令模式的核心,其抽象的命令代碼如下:

public abstract class Command {
  // 每個命令類都必須有一個執(zhí)行命令的方法
  public abstract void execute();
}

根據(jù)環(huán)境的需求,具體的命令類也可以有N個,其實現(xiàn)類如下:

public class ConcreteCommand1 extends Command {
  // 對哪個Receiver類進行命令處理
  private Receiver receiver;
  public ConcreteCommand1(Receiver receiver) {
    this.receiver = receiver;
  }
  // 必須實現(xiàn)一個命令
  public void execute() {
    // do something...
    // 業(yè)務處理
    this.receiver.doSomething();
  }
}

public class ConcreteCommand2 extends Command {
  // 對哪個Receiver類進行命令處理
  private Receiver receiver;
  public ConcreteCommand2(Receiver receiver) {
    this.receiver = receiver;
  }
  // 必須實現(xiàn)一個命令
  public void execute() {
    // do something...
    // 業(yè)務處理
    this.receiver.doSomething();
  }
}

這里定義了兩個具體的命令類,讀者可以在實際應用中擴展該命令類。在每個命令類中,通過構造函數(shù)定義了該命令是針對哪一個接收者發(fā)出的,定義一個命令接收的主體。

調用者Invoker類:

public class Invoker {
  private Command command;
  // 接受命令
  public void setCommand(Command _command) {
    this.command = _command;
  }

  // 執(zhí)行命令
  public void action() {
    this.command.execute();
  }
}

調用者就像是一個受氣包,不管什么命令,都要接收、執(zhí)行!

場景類如下:

public class Client {
  public static void main(String[] args) {
    // 首先聲明調用者Invoker
    Invoker invoker = new Invoker();
    // 定義接收者
    Receiver receiver = new ConcreteReciver1();
    // 定義一個發(fā)送給接收者的命令
    Command command = new ConcreteCommand1(receiver);
    // 把命令交給調用者執(zhí)行
    invoker.setCommand(command);
    invoker.action();
  }
}

優(yōu)點

  • 類間解耦
    調用者角色與接收者角色之間沒有任何依賴關系,調用者實現(xiàn)功能時只須調用Command抽象類的execute方法就可以,不需要關心到底是哪個接收者執(zhí)行;
  • 可擴展性
    Command的子類可以非常容易擴展,而調用者Invoker和高層的模塊Client不產(chǎn)生嚴重的代碼耦合;
  • 命令模式結合 其他模式更優(yōu)秀
    命令模式可以結合責任鏈模式,實現(xiàn)命令族解析任務;結合模板方法模式,則可以減少Command子類的膨脹問題。

缺點

命令模式也是有缺點的,請看Command的子類:如果有N個命令,問題就出來了,Command的子類就可不是幾個,而是N個,這個類膨脹得非常大,這個就需要我們在項目中慎重考慮使用。

使用場景

只要你認為是命令的地方就可以采用命令模式,例如,在GUI開發(fā)中,一個按鈕的點擊是一個命令,可以采用命令模式;模擬DOS命令的時候,當然也要采用命令模式;觸發(fā)——反饋機制的處理等;

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • 工廠模式類似于現(xiàn)實生活中的工廠可以產(chǎn)生大量相似的商品,去做同樣的事情,實現(xiàn)同樣的效果;這時候需要使用工廠模式。簡單...
    舟漁行舟閱讀 8,116評論 2 17
  • 目錄 本文的結構如下: 什么是命令模式 為什么要用該模式 模式的結構 代碼示例 優(yōu)點和缺點 適用環(huán)境 模式應用 總...
    w1992wishes閱讀 1,233評論 2 9
  • 【學習難度:★★★☆☆,使用頻率:★★★★☆】直接出處:命令模式梳理和學習:https://github.com/...
    BruceOuyang閱讀 926評論 0 3
  • 2018.7.8 對你的意想不到 意想不到今天扎針第三天你就能獨自走三五步! 意想不到你今天扎針只哭了一會會! 意...
    老姐嘛嘛閱讀 171評論 0 0

友情鏈接更多精彩內(nèi)容