設計模式之Command
板橋里人 http://www.jdon.com
模式實(shí)戰書(shū)籍《Java實(shí)用系統開(kāi)發(fā)指南》
Command模式是最讓我疑惑的一個(gè)模式,我在閱讀了很多代碼后,才感覺(jué)隱約掌握其大概原理,我認為理解設計模式最主要是掌握起原理構造,這樣才對自己實(shí)際編程有指導作用.Command模式實(shí)際上不是個(gè)很具體,規定很多的模式,正是這個(gè)靈活性,讓人有些confuse.
Command定義
n 將來(lái)自客戶(hù)端的請求傳入一個(gè)對象,無(wú)需了解這個(gè)請求激活的 動(dòng)作或有關(guān)接受這個(gè)請求的處理細節。
這是一種兩臺機器之間通訊聯(lián)系性質(zhì)的模式,類(lèi)似傳統過(guò)程語(yǔ) 言的 CallBack功能。
優(yōu)點(diǎn):
解耦了發(fā)送者和接受者之間聯(lián)系。 發(fā)送者調用一個(gè)操作,接受者接受請求執行相應的動(dòng)作,因為使用Command模式解耦,發(fā)送者無(wú)需知道接受者任何接口。
不少Command模式的代碼都是針對圖形界面的,它實(shí)際就是菜單命令,我們在一個(gè)下拉菜單選擇一個(gè)命令時(shí),然后會(huì )執行一些動(dòng)作.
將這些命令封裝成在一個(gè)類(lèi)中,然后用戶(hù)(調用者)再對這個(gè)類(lèi)進(jìn)行操作,這就是Command模式,換句話(huà)說(shuō),本來(lái)用戶(hù)(調用者)是直接調用這些命令的,如菜單上打開(kāi)文檔(調用者),就直接指向打開(kāi)文檔的代碼,使用Command模式,就是在這兩者之間增加一個(gè)中間者,將這種直接關(guān)系拗斷,同時(shí)兩者之間都隔離,基本沒(méi)有關(guān)系了.
顯然這樣做的好處是符合封裝的特性,降低耦合度,Command是將對行為進(jìn)行封裝的典型模式,Factory是將創(chuàng )建進(jìn)行封裝的模式,
從Command模式,我也發(fā)現設計模式一個(gè)"通病":好象喜歡將簡(jiǎn)單的問(wèn)題復雜化, 喜歡在不同類(lèi)中增加第三者,當然這樣做有利于代碼的健壯性 可維護性 還有復用性.
如何使用?
具體的Command模式代碼各式各樣,因為如何封裝命令,不同系統,有不同的做法.下面事例是將命令封裝在一個(gè)Collection的List中,任何對象一旦加入List中,實(shí)際上裝入了一個(gè)封閉的黑盒中,對象的特性消失了,只有取出時(shí),才有可能模糊的分辨出:
典型的Command模式需要有一個(gè)接口.接口中有一個(gè)統一的方法,這就是"將命令/請求封裝為對象":
| public interface Command { |
具體不同命令/請求代碼是實(shí)現接口Command,下面有三個(gè)具體命令
| public class Engineer implements Command { public class Programmer implements Command { public class Politician implements Command { |
按照通常做法,我們就可以直接調用這三個(gè)Command,但是使用Command模式,我們要將他們封裝起來(lái),扔到黑盒子List里去:
| public class producer{ } |
這三個(gè)命令進(jìn)入List中后,已經(jīng)失去了其外表特征,以后再取出,也可能無(wú)法分辨出誰(shuí)是Engineer 誰(shuí)是Programmer了,看下面客戶(hù)端如何調用Command模式:
| public class TestCommand { } |
由此可見(jiàn),調用者基本只和接口打交道,不合具體實(shí)現交互,這也體現了一個(gè)原則,面向接口編程,這樣,以后增加第四個(gè)具體命令時(shí),就不必修改調用者TestCommand中的代碼了.
理解了上面的代碼的核心原理,在使用中,就應該各人有自己方法了,特別是在如何分離調用者和具體命令上,有很多實(shí)現方法,上面的代碼是使用"從List過(guò)一遍"的做法.這種做法只是為了演示.
使用Command模式的一個(gè)好理由還因為它能實(shí)現Undo功能.每個(gè)具體命令都可以記住它剛剛執行的動(dòng)作,并且在需要時(shí)恢復.
Command模式在界面設計中應用廣泛.Java的Swing中菜單命令都是使用Command模式,由于Java在界面設計的性能上還有欠缺,因此界面設計具體代碼我們就不討論,網(wǎng)絡(luò )上有很多這樣的示例.
參考:
http://www.patterndepot.com/put/8/command.pdf
http://www.javaworld.com/javaworld/javatips/jw-javatip68.html
設計模式如何在具體項目中應用見(jiàn)《Java實(shí)用系統開(kāi)發(fā)指南》
聯(lián)系客服