java之命令模式,java命令
實際生活中常有的例子,比如銀行吧,在早些年,到銀行辦理業務,一堆人圍著大堂經理問,什麼業務該去什麼地方辦理,哎。。。。,一個問題一天要跟上百號人都解釋一遍,你好,這個業務呢,你可以去XX櫃檯諮詢一下,那這個業務呢,你可以去XY櫃檯諮詢,有時候,可能出現錯誤,返回來回問好幾遍,好煩哦。。。。,經理是何等的無奈,但為了客戶至上的原則,總是微笑,在微笑。何時是解脫之日啊。哈哈,隨著科技的發展,經理們終於從這苦難的日子裡解脫了,那就是業務辦理區取號機,現在簡單的操作就可以耐心等候辦理,既方便客戶,也解脫了經理,真是造福福士的一件好事。根據辦理業務的不同,系統自動分發給各自擅長的業務員哪裡,按著號碼一次處理。言歸正傳,上面的例子就命令模式的真實寫照,業務辦理取號機,將客戶的對於業務的請求,統一的接納,進行分類處理,對於不同的業務,安排到不同的業務員手中處理,避免之前繁瑣的過程。
命令模式的定義:Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undoable operations.(將一個請求封裝成一個對象,從而讓你使用不同的請求把用戶端參數化,請求排隊或者記錄請求日誌,可以提供命令的撤銷和恢複功能),說白了,就是把請求封裝成對象,以統一應對不同的請求,做出響應。
命令模式的通用圖解:
解釋上述圖解的關鍵詞:
Client:建立一個具體的命令對象(ConcreteCommand1 or ConcreteCommand2 ...)並設定它的接收者(ConcreteReceiver1 or ConcreteReceiver2....), 說白了,就是寫個測試類別,建立命令對象和接收者對象初始化一個Invoker,測試命令模式。在實際生活中,對於一個系統,有各種不同的請求,系統無法知道,發送來的請求要什麼Command處理和這個Command的最終處理者,就需要有一個總代理就像我們項目的介面人(Invoker)一樣,某個涉及到項目的問題先問介面人,然後介面人在安排,哪一個功能小組(具體的Command),小組再安排具體誰來處理(具體的Receiver),而一般發問題的一方,都知道是哪個更能模組出了問題,該找誰解決,但我們都有自己的事,如果這來問一下,那來問一下,那還怎麼工作。介面人就可以讓工作有秩序的進行。這樣下來,接收者也就是想我們一樣,屌絲碼農,不用跟其他項目的人直接打交道,也避免了,很多麻煩,同樣也使得我們的工作,更專註,更高效,不是???
Invoker:要求該命令執行這個請求,安排人,解決問題,包括Command的屬性參數,Command的set方法,和引用Command的execute()方法實現的Action()方法
Command : 聲明執行操作的介面,抽象類別,ConcreteCommand 繼承該 Command,具體該是用什麼操作處理這事?哪個功能小組能處理這事?至少包括一個execute()方法,或者可以加一個Receiver,更抽象一層,那麼ConcreteCommand,就好不用包括Receiver,只要初始化就好
ConcreteCommand:將一個接收者對象綁定在某一個動作上,調用接收者的相應操作,以實現Execute的方法,繼承自Command,實現execute方法,包括Receiver,用Receiver來實現execute方法
Receiver:知道如何實施和執行一個請求的相關操作,任何類都可可以作為一個接收者,可以是類或者抽象類別,抽象類別有對應ConcreteReceiver實現
同時注意根據定義,對於Command中應該包括,命令撤銷執行和恢複的狀態的功能,具體的在Command添加相關方法,在具體實作類別中實現即可
代碼實現例子:
1 public class Invoker 2 { 3 private Command command; 4 5 /** 6 * 設定 command 7 * 8 * @param command 對 command 進行賦值 9 */ 10 public void setCommand(Command command) 11 { 12 this.command = command; 13 } 14 15 public void action() 16 { 17 command.execute(); 18 } 19 } 20 21 public abstract class Command 22 { 23 public abstract void execute(); 24 } 25 26 public class ConcreteCommand1 extends Command 27 { 28 private Receiver receiver; 29 /** 30 * @param receiver 31 */ 32 public ConcreteCommand1(Receiver receiver) 33 { 34 this.receiver = receiver; 35 } 36 37 /** { @inheritDoc } */ 38 public void execute() 39 { 40 receiver.doSomething(); 41 } 42 43 } 44 45 public class ConcreteCommand2 extends Command 46 { 47 private Receiver receiver; 48 /** 49 * @param receiver 50 */ 51 public ConcreteCommand2(Receiver receiver) 52 { 53 this.receiver = receiver; 54 } 55 56 /** { @inheritDoc } */ 57 @Override 58 public void execute() 59 { 60 receiver.doSomething(); 61 } 62 63 } 64 65 public abstract class Receiver 66 { 67 public abstract void doSomething(); 68 } 69 70 public class ConcreteReceiver1 extends Receiver 71 { 72 73 /** { @inheritDoc } */ 74 @Override 75 public void doSomething() 76 { 77 // TODO Auto-generated method stub 78 } 79 80 } 81 82 public class ConcreteReceiver2 extends Receiver 83 { 84 85 /** { @inheritDoc } */ 86 @Override 87 public void doSomething() 88 { 89 // TODO Auto-generated method stub 90 } 91 92 } 93 94 public class Client 95 { 96 public static void main(String[] args) 97 { 98 // 首先聲明調用者Invoker 99 Invoker invoker = new Invoker();100 // 定義接收者101 Receiver receiver = new ConcreteReceiver1();102 // 定義一個發送給接收者的命令103 Command command = new ConcreteCommand1(receiver);104 // 把命令交給調用者去執行105 invoker.setCommand(command);106 invoker.action();107 }108 }
命令模式的優缺點