GRASP 通用職責分配軟件設計模式 (原則)

      GRASP,全稱爲General Responsibility Assignment Software Pattern,即通用職責分配軟件模式,它由《UML和模式應用》(Applying UML and Patterns)一書做者Craig Larman提出。與其將它們稱之爲設計模式,不如稱之爲設計原則,由於它是站在面向對象設計的角度,告訴咱們怎樣設計問題空間中的類與分配它們的行爲職責,以及明確類之間的相互關係等,而不像GoF模式同樣是針對特定問題而提出的解決方案。所以GRASP站在一個更高的角度來看待面向對象軟件的設計,它是GoF設計模式的基礎。數據庫

       GRASP對象職責分配的基本原則,其核心思想是職責分配(Responsibility Assignment),用職責設計對象(Designing Objects with Responsibilities)它包含以下9個基本模式:編程

 

      1. 信息專家模式 (Information Expert Pattern)設計模式

      (1) 問題:給對象分配職責的通用原則是什麼?服務器

      (2) 解決方案:將職責分配給擁有履行一個職責所必需信息的類,即信息專家。架構

      (3) 分析:信息專家模式是面向對象設計的最基本原則。通俗點來說,就是一個類只幹該乾的事情,不應乾的事情不幹。在系統設計時,須要將職責分配給具備實現這個職責所須要信息的類。信息專家模式對應於面向對象設計原則中的單一職責原則。函數

 

      2. 創造者模式 (Creator Pattern)spa

      (1) 問題:誰應該負責產生類的實例?.net

      (2) 解決方案:若是符合下面的一個或者多個條件,則可將建立類A實例的職責分配給類B設計

  • B包含A代理

  • B聚合A

  • B擁有初始化A的數據並在建立類A的實例時將數據傳遞給類A

  • B記錄A的實例;

  • B頻繁使用A

      此時,咱們稱類B是類A對象的建立者。若是符合多個條件,類B聚合或者包含類A的條件優先。

      (3) 分析:建立對象是面向對象系統中最廣泛的活動之一,所以,肯定一個分配建立對象的通用職責很是重要。若是職責分配合理,設計就能下降耦合,提升設計的清晰度、封裝性和重用性。一般狀況下,若是對象的建立過程不是很複雜,則根據上述原則,由使用對象的類來建立對象。可是若是建立過程很是複雜,並且可能須要重複使用對象實例或者須要從外部注入一個對象實例,此時,能夠委託一個專門的工廠類來輔助建立對象。建立者模式與各類工廠模式(簡單工廠模式、工廠方法模式和抽象工廠模式)相對應。

 

      3. 低耦合模式 (Low Coupling Pattern)

      (1) 問題:怎樣支持低的依賴性,減小變動帶來的影響,提升重用性?

      (2) 解決方案:分配一個職責,使得保持低耦合度。

      (3) 分析:耦合是評價一個系統中各個元素之間鏈接或依賴強弱關係的尺度,具備低耦合的元素不過多依賴其餘元素。此處的元素能夠是類,也能夠是模塊、子系統或者系統。具備高耦合的類過多地依賴其餘類,這種設計將會致使:一個類的修改致使其餘類產生較大影響;系統難以維護和理解;系統重用性差,在重用一個高耦合的類時不得不重用它所依賴的其餘類。所以須要對高耦合的系統進行重構。

      類A和類B之間的耦合關係體現以下:A具備一個B類型的屬性;A調用B的方法;A的方法包含對B的引用,如方法參數類型爲B或返回類型爲BAB的直接或者間接子類;B是一個接口,A實現了該接口。低耦合模式鼓勵在進行職責分配時不增長耦合性,從而避免高耦合可能產生的不良後果。在進行類設計時,須要保持類的獨立性,減小類變動所帶來的影響,它一般與信息專家模式和高內聚模式一塊兒出現。爲了達到低耦合,咱們能夠經過以下方式對設計進行改進:

  • 在類的劃分上,應當儘可能建立鬆耦合的類,類之間的耦合度越低,就越有利於複用,一個處在鬆耦合中的類一旦被修改,不會對關聯的類形成太大波及;

  • 在類的設計上,每個類都應當儘可能下降其成員變量和成員函數的訪問權限;

  • 在類的設計上,只要有可能,一個類型應當設計成不變類;

  • 在對其餘類的引用上,一個對象對其餘對象的引用應當降到最低。

      4. 高內聚模式 (High Cohesion Pattern)

      (1) 問題:怎樣使得複雜性可管理?

     (2) 解決方案:分配一個職責,使得保持高內聚。

      (3) 分析:內聚是評價一個元素的職責被關聯和關注強弱的尺度。若是一個元素具備不少緊密相關的職責,並且只完成有限的功能,則這個元素就具備高內聚性。此處的元素能夠是類,也能夠是模塊、子系統或者系統。

      在一個低內聚的類中會執行不少互不相關的操做,這將致使系統難於理解、難於重用、難於維護、過於脆弱,容易受到變化帶來的影響。所以咱們須要控制類的粒度,在分配類的職責時使其內聚保持爲最高,提升類的重用性,控制類設計的複雜程度。爲了達到低內聚,咱們須要對類進行分解,使得分解出來的類具備獨立的職責,知足單一職責原則。在一個類中只保留一組相關的屬性和方法,將一些須要在多個類中重用的屬性和方法或完成其餘功能所需的屬性和方法封裝在其餘類中。類只處理與之相關的功能,它將與其餘類協做完成複雜的任務。

 

      5. 控制器模式 (Controller Pattern)

      (1) 問題:誰應該負責處理一個輸入系統事件?

      (2) 解決方案:把接收或者處理系統事件消息的職責分配給一個類。這個類能夠表明:

  • 整個系統、設備或者子系統;

  • 系統事件發生時對應的用例場景,在相同的用例場景中使用相同的控制器來處理全部的系統事件。

      (3) 分析:一個控制器是負責接收或者處理系統事件的非圖形用戶界面對象。一個控制器定義一組系統操做方法。在控制器模式中,要求系統事件的接收與處理一般由一個高級類來代替;一個子系統須要定義多個控制器,分別對應不一樣的事務處理。一般,一個控制器應當把要完成的功能委託給其餘對象,它只負責協調和控制,自己不完成太多的功能。它能夠將用戶界面所提交的請求轉發給其餘類來處理,控制器能夠重用,且不能包含太多業務邏輯,一個系統一般也不能設計一個統一的控制器。控制器模式與MVC模式相對應,MVC是一種比設計模式更加高級的架構模式。  

 

      6. 多態模式 (Polymorphism Pattern)

      (1) 問題:如何處理基於類型的不一樣選擇?如何建立可嵌入的軟件組件?

      (2) 解決方案:當相關選擇或行爲隨類型(類)變化而變化時,用多態操做爲行爲變化的類型分配職責。

      (3) 分析:由條件變化引起同一類型的不一樣行爲是程序的一個基本主題。若是用if-elseswitch-case等條件語句來設計程序,當系統發生變化時必須修改程序的業務邏輯,這將致使很難方便地擴展有新變化的程序。另外對於服務器/客戶端結構中的可視化組件,有時候須要在不影響客戶端的前提下,將服務器的一個組件替換成另外一個組件。此時可使用多態來實現,將不一樣的行爲指定給不一樣的子類,多態是設計系統如何處理類似變化的基本方法,基於多態分配職責的設計能夠方便地處理新的變化。在使用多態模式進行設計時,若是須要對父類的行爲進行修改,能夠經過其子類來實現,不一樣子類能夠提供不一樣的實現方式,將具體的職責分配給指定的子類。新的子類增長到系統中也不會對其餘類有任何影響,多態是面向對象的三大基本特性之一(另外兩個分別是封裝和繼承),經過引入多態,子類對象能夠覆蓋父類對象的行爲,更好地適應變化,使變化點可以「經得起將來驗證」。多態模式在多個GoF設計模式中都有所體現,如適配器模式、命令模式、組合模式、觀察者模式、策略模式等等。

 

      7. 純虛構模式 (Pure Fabrication Pattern)

      (1) 問題:當不想破壞高內聚和低耦合的設計原則時,誰來負責處理這種狀況?

      (2) 解決方案:將一組高內聚的職責分配給一個虛構的或處理方便的「行爲」類,它並非問題域中的概念,而是虛構的事務,以達到支持高內聚、低耦合和重用的目的。

      (3) 分析:純虛構模式用於解決高內聚和低耦合之間的矛盾,它要求將一部分類的職責轉移到純虛構類中,在理想狀況下,分配給這種虛構類的職責是爲了達到高內聚和低耦合的目的。在實際操做過程當中,純虛構有不少種實現方式,例如將數據庫操做的方法從數據庫實體類中剝離出來,造成專門的數據訪問類,經過對類的分解來實現類的重用,新增長的數據訪問類對應於數據持久化存儲,它不是問題域中的概念,而是軟件開發者爲了處理方便而產生的虛構概念。純虛構能夠消除因爲信息專家模式帶來的低內聚和高耦合的壞設計,獲得一個具備更好重用性的設計。在系統中引入抽象類或接口來提升系統的擴展性也能夠認爲是純虛構模式的一種應用。純虛構模式一般基於相關功能的劃分,是一種以功能爲中心的對象或行爲對象。在不少設計模式中都體現了純虛構模式,例如適配器模式、策略模式等等。

 

      8. 中介模式 (Indirection Pattern)

     (1) 問題:如何分配職責以免兩個(或多個)事物之間的直接耦合?如何解耦對象以下降耦合度並提升系統的重用性?

     (2) 解決方案:分配職責給中間對象以協調組件或服務之間的操做,使得它們不直接耦合。中間對象就是在其餘組件之間創建的中介。

      (3) 分析:要避免對象之間的直接耦合,最經常使用的作法是在對象之間引入一箇中間對象或中介對象,經過中介對象來間接相連。中介模式對應於面向對象設計原則中的迪米特法則,在外觀模式、代理模式、中介者模式等設計模式中都體現了中介模式。

 

      9. 受保護變化模式 (Protected Variations Pattern)

      (1) 問題:如何分配職責給對象、子系統和系統,使得這些元素中的變化或不穩定的點不會對其餘元素產生不利影響?

      (2) 解決方案:找出預計有變化或不穩定的元素,爲其建立穩定的「接口」而分配職責。

      (3) 分析:受保護變化模式簡稱PV,它是大多數編程和設計的基礎,是模式的基本動機之一,它使系統可以適應和隔離變化。它與面向對象設計原則中的開閉原則相對應,即在不修改原有元素(類、模塊、子系統或系統)的前提下擴展元素的功能。開閉原則又可稱爲「可變性封裝原則(Principle of Encapsulation of Variation, EVP)」,要求找到系統的可變因素並將其封裝起來。如將抽象層的不一樣實現封裝到不一樣的具體類中,並且EVP要求儘可能不要將一種可變性和另外一種可變性混合在一塊兒,這將致使系統中類的個數急劇增加,增長系統的複雜度。在具體實現時,爲了符合受保護變化模式,咱們一般須要對系統進行抽象化設計,定義系統的抽象層,再經過具體類來進行擴展。若是須要擴展系統的行爲,無須對抽象層進行任何改動,只須要增長新的具體類來實現新的業務功能便可,在不修改已有代碼的基礎上擴展系統的功能。大多數設計原則和GoF模式都是受保護變化模式的體現。

【做者:劉偉  http://blog.csdn.net/lovelion

相關文章
相關標籤/搜索