以前一直在忙於工做上的事情,關於設計模式系列一直沒更新,最近項目中發現,對於設計模式的瞭解是必不可少的,固然對於設計模式的應用那更是重要,能夠說是否懂得應用設計模式在項目中是衡量一個程序員的技術水平,由於對於一個功能的實現,高級工程師和初級工程師同樣都會實現,可是區別在於它們實現功能的可擴展和可維護性,也就是代碼的是否「優美」、可讀。可是,要更好地應用,首先就必須瞭解各類設計模式和其應用場景,因此我仍是但願繼續完成設計模式這個系列,但願經過這種總結的方式來加深本身設計模式的理解。html
命令模式屬於對象的行爲型模式。命令模式是把一個操做或者行爲抽象爲一個對象中,經過對命令的抽象化來使得發出命令的責任和執行命令的責任分隔開。命令模式的實現能夠提供命令的撤銷和恢復功能。程序員
既然,命令模式是實現把發出命令的責任和執行命令的責任分割開,然而中間必須有某個對象來幫助發出命令者來傳達命令,使得執行命令的接收者能夠收到命令並執行命令。例如,開學了,院領導說計算機學院要進行軍訓,計算機學院的學生要跑1000米,院領導的話也就至關於一個命令,他不可能直接傳達給到學生,他必須讓教官來發出命令,並監督學生執行該命令。在這個場景中,發出命令的責任是屬於學院領導,院領導充當與命令發出者的角色,執行命令的責任是屬於學生,學生充當於命令接收者的角色,而教官就充當於命令的發出者或命令請求者的角色,然而命令模式的精髓就在於把每一個命令抽象爲對象。從而命令模式的結構以下圖所示:設計模式
從命令模式的結構圖能夠看出,它涉及到五個角色,它們分別是:網絡
如今,讓咱們以上面的軍訓的例子來實現一個命令模式,在實現以前,能夠參考下命令模式的結構圖來分析下實現過程。app
軍訓場景中,具體的命令便是學生跑1000米,這裏學生是命令的接收者,教官是命令的請求者,院領導是命令的發出者,即客戶端角色。要實現命令模式,則必須須要一個抽象命令角色來聲明約定,這裏以抽象類來來表示。命令的傳達流程是:ide
命令的發出者必須知道具體的命令、接受者和傳達命令的請求者,對應於程序也就是在客戶端角色中須要實例化三個角色的實例對象了。post
命令的請求者負責調用命令對象的方法來保證命令的執行,對應於程序也就是請求者對象須要有命令對象的成員,並在請求者對象的方法內執行命令。this
具體命令就是跑1000米,這天然屬於學生的責任,因此是具體命令角色的成員方法,而抽象命令類定義這個命令的抽象接口。spa
有了上面的分析以後,具體命令模式的實現代碼以下所示:設計
1
2 // 教官,負責調用命令對象執行請求 3 public class Invoke 4 { 5 public Command _command; 6 7 public Invoke(Command command) 8 { 9 this._command = command; 10 } 11 12 public void ExecuteCommand() 13 { 14 _command.Action(); 15 } 16 } 17 18 // 命令抽象類 19 public abstract class Command 20 { 21 // 命令應該知道接收者是誰,因此有Receiver這個成員變量 22 protected Receiver _receiver; 23 24 public Command(Receiver receiver) 25 { 26 this._receiver = receiver; 27 } 28 29 // 命令執行方法 30 public abstract void Action(); 31 } 32 33 // 34 public class ConcreteCommand :Command 35 { 36 public ConcreteCommand(Receiver receiver) 37 : base(receiver) 38 { 39 } 40 41 public override void Action() 42 { 43 // 調用接收的方法,由於執行命令的是學生 44 _receiver.Run1000Meters(); 45 } 46 } 47 48 // 命令接收者——學生 49 public class Receiver 50 { 51 public void Run1000Meters() 52 { 53 Console.WriteLine("跑1000米"); 54 } 55 } 56 57 // 院領導 58 class Program 59 { 60 static void Main(string[] args) 61 { 62 // 初始化Receiver、Invoke和Command 63 Receiver r = new Receiver(); 64 Command c = new ConcreteCommand(r); 65 Invoke i = new Invoke(c); 66 67 // 院領導發出命令 68 i.ExecuteCommand(); 69 } 70 }
在ASP.NET的MVC模式中,有一種叫Front Controller的模式,它分爲Handler和Command樹兩個部分,Handler處理全部公共的邏輯,接收HTTP Post或Get請求以及相關的參數並根據輸入的參數選擇正確的命令對象,而後將控制權傳遞到Command對象,由其完成後面的操做,這裏面其實就是用到了Command模式。
Front Controller 的處理程序部分結構圖
Front Controller的命令部分結構圖
Handler 類負責處理各個 Web 請求,並將肯定正確的 Command 對象這一職責委派給 CommandFactory 類。當 CommandFactory 返回 Command 對象後,Handler 將調用 Command 上的 Execute 方法來執行請求。具體的實現以下
在下面的狀況下能夠考慮使用命令模式:
命令模式使得命令發出的一個和接收的一方實現低耦合,從而有如下的優勢:
命令模式的缺點:
命令模式的實現要點在於把某個具體的命令抽象化爲具體的命令類,並經過加入命令請求者角色來實現將命令發送者對命令執行者的依賴分割開,在上面軍訓的例子中,若是不使用命令模式的話,則命令的發送者將對命令接收者是強耦合的關係,實現代碼以下:
1 // 院領導 2 class Program 3 { 4 static void Main(string[] args) 5 { 6 // 行爲的請求者和行爲的實現者之間呈現一種緊耦合關係 7 Receiver r = new Receiver(); 8 9 r.Run1000Meters(); 10 } 11 } 12 13 public class Receiver 14 { 15 // 操做 16 public void Run1000Meters() 17 { 18 Console.WriteLine("跑1000米"); 19 } 20 }
到這裏,本章的內容就介紹結束了,在下一章將繼續爲你們分享下我對迭代器模式的理解。
注:轉自http://www.cnblogs.com/zhili/p/CommandPattern.html