大白話講解設計模式之命令模式

初衷:

看了一些命令模式的博客,仍然不知道如何實現一個命令模式,如何設計,以及爲何這麼設計,本文通過一個例子來說明命令模式的設計過程以及這麼設計的原因。

命令模式分解:

命令模式從組成上分爲:

  • 命令(Command)
  • 調用者 (invoker)
  • 客戶端 (client)
  • 命令接收者 (receiver)

其中,命令的具體實現類可以有多個,即可以有多個命令。
調用者爲統一處理命令,讓命令接收者執行命令,只有一個。
客戶端爲發起命令的主體。
命令接收者爲具體的命令執行者。

接下來,我們看看具體的例子來理解何爲命令模式,如何設計。
eg:PM要給RD提出各種各樣的需求和修改,但需要在需求評審會上進行需求評審,由Leader拍板是不是做,PM說,RD,請實現APP的界面顏色隨着用戶手機殼顏色的變化而變化,Leader一聽,有意思,做起來,然後給RD下達了命令,RD一看需求無能爲力,將無法實現的結果告訴Leader,Leader將最終結果反饋給PM。
在這個例子中,PM(客戶端)發出了命令,命令包括了兩部分內容:

  1. RD(命令的接收者)
  2. APP界面顏色隨着手機殼顏色變化而變化(接收者需要做的具體操作)

然後PM(客戶端)不直接去找RD(receiver),需要找Leader(invoker)進行需求評審,Leader(invoker)需要作出一些判斷或者前置後置處理,再讓RD(接收者)執行具體的命令。

如何設計命令模式

這就是一個命令模式的例子,通過例子我們可以思考,如何設計命令模式:
參考上述命令模式的組成,我們分別設計:

設計命令:

有例子可以看出,一個具體的命令包括了具體的命令接收者和具體的執行操作,又由於可以有很多個命令,所以需要將命令進行抽象化,即接口或者抽象類:

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

具體的命令類需要包括兩個部分,一是實現抽象類的方法,即命令的具體操作,二是新增命令的執行者屬性。

public class ConcreteCommand extends Command {
     //對哪個Receiver類進行命令處理
     private Receiver receiver; 
     //構造函數傳遞接收者
     public ConcreteCommand(Receiver _receiver){
             this.receiver = _receiver;
     }
     //必須實現一個命令
     public void execute() {
             //業務處理
             this.receiver.doSomething();
     }
}

設計調用者:

根據上述的Leader(invoker),他需要知道PM的具體命令,所以他需要有一個命令的成員變量,然後他需要經過一些操作後讓RD(接收者)開始執行命令,所以他一個執行方法。

public class Invoker {
     private Command command;
     //設置命令
     public void setCommand(Command _command){
             this.command = _command;
     }
     //執行命令
     public void action(){
             this.command.execute();
     }
}

設計接收者:

RD(接收者)負責執行命令,需要對外暴露自己的能力,比如RD需要讓PM知道自己會寫bug,這樣PM有寫bug的需求才會給RD發出命令。又因爲有好多RD,所以需要抽象一下,每個具體的RD繼承該類。

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

設計客戶端:

PM(客戶端)是一個調用者,他負責發出一些無理的需求(命令,包括接收者和具體操作),然後告訴Leader(incoker),由Leader反饋給他最後的執行結果

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

優缺點

通過上面的設計可以看出,優點就是:解決了命令發起者和實現者直接的高耦合的關係,新添加一個命令也很容易。缺點是: 可能會因爲命令的增多而導致命令類過多。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章