設計模式GRASP和GoF是怎樣解決耦合的問題

設計模式GRASP和GoF是怎樣解決耦合的問題

關鍵字: 解藕 耦合
 

最近網友Uranus問我了一個非常有趣的問題:設計模式GRASPGoF是怎樣解決耦合的問題?實際上雖然同是設計模式,解決對象間耦合的問題都是它們的終極目標,但是它們在解決它們的方式上卻是完全不同的,GRASP是從整體設計上解決耦合的問題,而GoF卻是從具體實現上解決的,在這裏我們不妨探討一下。

設計模式GRASP其名稱翻譯過來就是“通用職責分配設計模式”,從字面上我們不難發現,“職責分配”是GRASP的核心。GRASP認爲,在對象設計時,只要各個對象的職責分配清楚了,能夠各司其職,耦合就會降低。因此,GRASP應用的一個非常重要的場景是,我們項目的業務需求已經分析清楚了,正準備開始設計對象。GRASP告訴我們,一個系統裏面到底應當有哪些對象,應當來源於領域模型,換句話說就是來源於現實時間中的事物。現實世界中有什麼事物,我們軟件空間中就應當有什麼對象。當然,現實世界中的事物不一定都需要在軟件空間中有對應的對象,要根據需求而定,但軟件空間中的對象應當對應於現實世界中的事物,這種設計原則有個專用術語叫“低表示差異”。按照這個原則設計好了我們的對象以後,應當如何分配它們的職責呢?當然是來源於現實世界。我們的對象在現實世界中應當有什麼職責,那麼我們的對象就應當有什麼樣的職責。如此分析,每個對象的職責就非常清楚,那麼業務需求中的各種功能應當如何分配給對象呢?現實世界是怎樣分配的,軟件世界就怎樣分配的。最後,如何在各個功能中將對象組織起來呢?GRASP的專家模式解答了這個問題;對象應當由誰來創建,GRASP的創建者模式解答了這個問題。GRASP通過這樣一個步驟,設計對象、分配職責、確定功能、建立聯繫,一個項目的整體框架就展現出來了,而這樣一個框架必然是低耦合高內聚的,爲什麼呢?這方面的詳細論述朋友們可以看我寫的《(原創)一個優秀軟件開發人員的必修課:GRASP軟件開發模式淺析》,這裏我就不再累贅了。但是,GRASP只解決了整體設計中的耦合問題,只解決了一部分,而另一部分需要依靠GoF

前面我們說到運用GRASP進行整體設計依靠的是現實世界和業務需求。這樣的分析還沒有介入任何技術的成分。但是隨着我們的進一步分析,我們開始嘗試運用各種具體的技術去實現這些業務需求需要實現的功能,我們發現問題出現了。比如,我們在整體設計的時候設計的一組繼承關係的對象,其它需要使用它們的對象如何去調用它們?去具體地調用它們的某個子類嗎?這顯然不是一個好的方案,GoF的工廠模式告訴我們,這裏需要設計一個工廠類。這裏增加的這個工廠類不是來源於現實世界,GRASP稱這樣的對象爲“純虛對象”。純虛對象是從現實對象中抽象出來的一些功能,但GRASP不能告訴我們應當抽象出哪些純虛對象,解決這樣的問題需要運用GoF。再比如,商場中的許多商品都需要打折,但是各種商品的打折策略其實並不是完全不同的,是有相似之處的,有的是按比例打折,有的是滿500100,有的是學生纔打折。如此這般,如果我們對一個商品父類的所有商品子類都重載一遍自己“折扣”方法,顯然不是一個好的設計,不如將所有的折扣方法抽象出來,形成抽象的“折扣策略”父類和具體的折扣子類,然後由各個商品子類自己去選擇自己需要的折扣策略。如此這般,就運用了GoF的策略模式。通過以上分析,我們不難看出,GoF是在具體實現中去解決對象的耦合問題的。它是在GRASP分析的整體框架下,對一些具體的對象及其方法進行重新組織,解決對象耦合問題的。

現在,我們再換一個角度,從整個軟件開發過程來分析GRASPGoF。按照RUP的設計流程,首先當然是設計用例模型和領域模型,然後就進入分析模型和設計模型階段。但是非常神奇的是,分析模型和設計模型既非常相似,又沒有一個明顯的界限來區分哪些是分析模型,哪些是設計模型。按照我的理解,分析模型是從不包含任何技術的,純業務的角度開始對象分析的。不論是Java的項目、C++的項目還是Delphi的項目,不論是B/S的結構還是C/S的結構,分析模型的開始都是一樣的。從分析模型的一開始,就是運用GRASP一步一步的進行對象分析和設計的。通過這樣的設計,對應於現實世界的一個一個對象被設計出來,然後賦予它們職責和功能,分配它們屬性和方法,建立起它們相互之間的聯繫與協作。分析完這些以後,它們的各個具體的屬性和方法就需要開始實現,這時技術的東西開始介入,我們開始考慮把一些具體的實現抽象爲接口和抽象類,以適應今後的需求變化。這時候,GoF的一些設計模式開始廣泛運用,純虛對象開始一個一個出現。把具體的實現抽象爲接口和抽象類,以適應今後的需求變化,是GoF一個非常重要的設計原則,GoF中的許多設計模式都是由此而生的。分析模型和設計模型的界線也許就是分析模型還僅僅只是分析階段,而設計模型已經進入到了軟件開發階段,但這樣的界線是模糊的,並沒有一個絕對的時間點。

最後,一個很有意思的問題是,GRASP的作用大還是GoF的作用大?做分析的朋友可能說GRASP的作用大,因爲所有問題越是在項目開發的早期解決,越是給項目帶來的代價越小;做設計的朋友可能會說GoF的作用大,因爲GRASP只是在對象分析的初期運用,而GoF的運用貫穿整個軟件設計的始末,作用時間更長。我認爲這個問題不好回答,它們各司其職,我們只有配合使用它們纔能有效地提高我們的設計水平。
評論
fangang 2007-05-15   回覆
GRASP更多運用於系統分析
GoF更多運用於設計開發
dovecat 2007-05-14   回覆
...呵呵~~挑明瞭說吧:
GRASP運用於理解真實環境和概念上的設計,
GOF就是代碼和實現的設計.
上下都會有影響.
兩者之見就是鴻溝
Uranus 2007-05-14   回覆
看懂你的意思了,設計與實現的關係,我在好好想想。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章