GRASP (物件導向設計)

GRASP通用職責分配軟體模式(General Responsibility Assignment Software Patterns)的簡稱,是物件導向設計和職責分配中的九個基本原則[1]:6,最早是在克雷·拉蒙英語Craig Larman1997年的Applying UML and Patterns書中提到。

GRASP中提到的模式和原則包括有控制器(controller)、建立者(creator)、中介(indirection)、資訊專家(information expert)、低耦合性(low coupling)、高內聚性(high cohesion)、多型(polymorphism)、保護變化(protected variations)和純虛構(pure Fabrication)[2]。這些模式都是針對軟體開發上的一些問題進行解決。發明這些技巧不是為了要創造新的工作方式,而是為在物件導向設計上,舊的,經過測試的程式設計方式建立文件並且標準化。

克雷·拉蒙提到:「軟體開發最關鍵的設計工具不是UML或其他的技術,是明瞭設計原則的心智。」[3]:272。因此,GRASP原則是心理層面的工具集,在物件導向軟體設計學習上的輔助工具。

模式

在物件導向設計中,設計模式是針對問題以及其解決方案一個有命名的描述方式,可以應用在不同的情境中。理想的設計模式可以讓程式開發者知道要如何將解決方案應用在不同的環境下,並且進行取捨。在一些特定類型的問題中,許多模式會提供物件職責分配的指南。

資訊專家

問題: 分配職責給物件的基本原則是什麼?
解決方案:找到實現職責需要有的資訊,將職責分配給有此資訊的物件

資訊專家(Information expert)是決定如何分配職責(給方法、欄位等)的原則。

應用資訊專家的原則,常見指定職責的作法是針對特定的職責,確認要實現此職責要有什麼資訊,以及資訊存在的物件。

這會將職責分配到有最多和職責有關資訊的物件[3]:17:11

相關模式或原則:低耦合性、高內聚性

建立者

物件的建立是物件導向系統中常見的活動之一。因此需要確認哪一個類別有職責建立物件。

問題:哪個類別要建立物件A?
解決方案:一般而言,類別B若符合以下一個(也有可能是多個)條件,有權責要建立物件A

  • B的實例包括A的實例,或是合成聚合A的實例
  • B的實例會紀錄A的實例
  • B的實例密切的使用A的實例
  • B的實例有A的實例初始化時的資訊,在建立物件時會傳遞給A的實例[3]:16:16.7

相關模式或原則:低耦合性、工廠方法

控制器

控制器(controller)模式會將處理系統物件的職責指定給表現整個系統或是用例場景的非使用者介面類別。控制器物件是非使用者介面,負責接收或處理系統事件的物件。

問題:哪個物件要處理輸入系統事件?
解決方案:應該由用例控制器來處理用例所有的系統事件,也可以用在一個以上的用例。例如「建立使用者」或「刪除使用者」的用例,可以用同一個類別,稱為UserController,而不是用二個個別的用例控制器。

控制器定義為在使用者介面之後,接收及處理系統動作的第一個物件。控制器需將需其他物件來完成的工作給對應物件。控制器協調或是控制相關活動。在資訊系統邏輯架構的物件導向系統中,若應用程式在應用層/服務層和業務邏輯之間有明確的分隔,GRASP控制器可以視為是應用層或是服務層的一部份[4]

相關模式或原則:命令模式外觀模式、純虛構

中介

中介(indirection)模式支援低耦合性,在二個物件之間將其職責指定到中介的物件,因此可以復用。其中一個例子是在模型—視圖控制模式中,在資料(模型)和其實現(視圖)之間匯入控制器元件。這可以確保二個元件之間的低耦合性。

問題: 在二個或多個物件之間,要如何分配職責才能避免耦合?如何將物件解耦,才能支援低耦合度,且維持較高的復用潛力?

解決方案:將職責分配給二個或多個元件之間的中介物件或服務,讓元件之間不會直接耦合

低耦合性

耦合性是評估一元件連結另一元件,知道另一元件,或是依賴另一元件的程度。鬆耦合是為了以下的優點,指派職責的評估模式:

  • 類別之間的相依性低
  • 一個類別的修改對另一個類別的影響較小
  • 復用潛力較高

高內聚性

高內聚性(high cohesion)是設法讓物件適當的聚焦、可管理以及可理解的評估模式。高內聚性常常會用來支援低耦合性。高內聚性是指特定元件的多個職責是彼此緊密有關,高度聚焦的。將程式分解為類別和子系統是增加系統內聚性的一種方式。相對的,低內聚性是指特定元件有太多不相關的職責。低內聚性的元件常會難以理解、復用、維護及改變[3]:314–315

多型

依照多型(polymorphism)的原則,依型態變更行為的職責是在出現變更的型態上。這可以用多型運算子實現。這類型態的使用者需要用多型運算子。

問題: 如何處理依型態的變化?如何產生可可插拔的軟體元件?
解決方案:當一些行為會因為型態(類別)而變化,用多型運算子將此職責分派到型態出現變化的型態。(多型有許多的定義,在此處的定義是「在不同物件上的服務給予相同的名字」)

保護變化

保護變化(protected variations)模式保護元件,不受其他元件(物件、系統、子系統)變化的影響,作法是將聚焦在不穩定部份的程式包裹在介面內,利用多型來產生此一介面的不同實現。

問題: 如何設計物件、子系統和系統,讓元件的變化或不穩定性不會對其他元件有不好的影響?
解決方案:識別預期到的變互斥或不穩定性,指定職責在其週圍產生穩定的介面。

純虛構

純虛構(pure fabrication)是指沒有實現問題領域概念的類別,特別是為了實現衍生類別低耦合性、高內聚性、高復用的潛力(若是用資訊專家的解決方案,無法達到此一效果)。這類類別在領域驅動設計中會稱為服務。

相關模式或原則:

  • 低耦合性
  • 高內聚性

相關條目

參考資料

  1. ^ Craig Larman. Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and the Unified Process (PDF) 2nd. Prentice Hall. 2001 [2021-04-22]. ISBN 0-13-092569-1. (原始內容 (PDF)存檔於2021-04-22). 
  2. ^ Muhammad Umair. SOLID, GRASP, and Other Basic Principles of Object-Oriented Design. DZone. 2018-02-26 [2021-04-22]. (原始內容存檔於2021-04-22). 
  3. ^ 3.0 3.1 3.2 3.3 Craig Larman. Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development 3rd. Pearson. 2004. ISBN 978-0131489066. 
  4. ^ Application Layer like business facade?. Yahoo! Groups (domaindrivendesign). [2010-07-15]. (原始內容存檔於2020-08-07).