哈哈,大家新年快樂。本來說要盡快把這個話題結束的,結果因為考試,我的Open source的project而拖到了現在。今天和明天盡可能的結束它們吧~謝謝大家的支持,也對我的拖延表示歉意。。。
與前兩種模式不同,一些行為型模式需要在動態過程中才能被良好的表達,這也給這些模式的理解加深了難度。特別是在對已有系統進行逆向分析的時候,對于一些混合使用了多個設計模式的組件而言,想準確的弄清楚用了哪些模式,更是困難。所以對設計模式使用動機的理解,是很重要的。
這個是題外話。
首先來討論一下Chain of responsibility
。
對于職責鏈來說,“鏈”這個詞是關鍵。
它的一個隱含的意義就是,消息的散播有序的。這種序列可以表現為主從關系,或先后關系。
在運行時,消息的傳播完全有可能是樹狀或者呈現DAG這樣的結構(例如在composite中)。它適合于消息傳播層次化的時候,如果不同對象之間的消息溝通是呈現復雜的網狀或者扁平狀,那么消息鏈就完全沒有作用了。
如果消息的傳遞可以是無序的,或者不同消息接受者之間沒有明顯的主從關系,那么更適合用一些更加靈活的手法,比如signal-slot idioms。不過,signal slot與COR的關注點并不同,前者比后者要更加關注與實現細節和消息通訊的局部情況。
COR和Decorator也有一些相似之處的,只不過COR的關系是在動態過程中體現,而Decorator是在靜態過程中體現;并且COR只是強調信息的轉發,而Decorator則是強調功能的增強。前者強調模式的協作組件間提供一個機制,以及怎樣實現這個機制;后者則強調模式的協作組件之間需要什么樣的功能邏輯。
Command是個非常強大的工具,它的強大與難以理解對很多初學者來說都是很可怕的事情。
但是對于Command的基本理解,只需要知道它是C++版的Callback,就足夠了。同時,對于Command的使用,我認為也僅限于Callback,如果Command的職責超出了Callback之外的用途,是需要謹慎對待的。Command解決了消息內容與組件之間的耦合問題,但是,它并沒有解決交互耦合的問題。
以UI設計為例,使用Command可以將UI元素與邏輯之間互相不知道對方的內容。但是,在僅僅有Commmad的情況下,邏輯必須知道“UI”的基本情況才能正確運行(比方說與UI一起工作,Command需要綁定哪些要素)。實際上我們對它的期望是,邏輯部分不知道UI的存在,無論是Command Line下(此Command非彼Command,哈哈)還是GUI下,甚至作為一個系統的子系統出現,它都能正常的工作。而為與UI協同工作的Command很有可能就具備了UI下的Command實現所特有的特征。這些特征在移植到其它環境下會有一些困難,并需要做出設計上的再度取舍,Command模式本身也成為了一個包袱。
其次,Command模式通常用于多對多的關系中,這使得Command在時間上和邏輯上不連貫,也會給系統理解帶來一定的難度。因此,如果將Command與Mediator或者COR、或者Visitor這樣的模式搭配使用,將Command理解為實踐技術與慣用手法,而將Mediator等作為設計元素來考慮的話,可能更加恰當一些。Command提供了消息的解耦合,而其它的模式則連同通信耦合也一并解除了。
Interpretor恐怕是DP里面所討論的用途最窄的模式了。
實際上,稍微有點經驗的人,對這個模式都不陌生。Composite,Interpretor和Builder之間有著千絲萬縷的聯系。前者體現了結構上的層次,Builder則適合于構造Composite,而Interpretor,可以作為Builder用于構造Composite的信息源。從更加寬泛的概念講,Interpretor適合于將一種層次化的信息轉換成另外一種表達方式。最典型的例子就是帶有子結構的類的I/O實現,例如將對象持久化為XML或者逆持久化,在這里面就少不了它的身影。