通用職責分配軟體模式概要 | General Responsibility Assignment Software Patterns, GRASP

工程師的秘密武器雀老師!! 圖片來源
情境
“ 最嚴重的錯誤並非來自錯誤的答案,真正危險的是問錯了問題。 ”
有沒有遇過遇到一個物件的創建邏輯會寫得很長,此時經驗告訴你,寫在建構子會不太妙,會超過你在網路上看到的一個類別不能超過200行還是80行,該怎麼辦?
然後你問 ChatGPT,發現有個工廠模式可以用,然後很快的,ChatGPT 把改良後的程式碼給打了出來,複製貼上,ChatGPT 我的超人。

ChatGPT 快救救我呀,圖片來源
隔天的 code review,面對 mentor 的好心提問,為什麼這個類別,名稱後面有一個 Factory ? 為什麼要使用工廠模式?
面對看不懂的人,他們會說,我覺得寫在同一個類別這樣我只要開一個檔案就能全部看見就好,幹嘛搞這麼複雜? 此時你除了說會超過200行以外,還能說些甚麼?
GRASP 概論
“ GRASP原則或模式是一種學習工具,它能幫助你理解基本物件設計,並以一種系統的、合理的、可解釋的方式來運用設計推理 ”
在這個上面例子中200行說不定只是實踐設計原則的所產生的結果,一種良好的副產品。在解答越來越容易取得的當下,脈絡的澄清變得十分重要,這有助於理解為甚麼是這個答案以及多個解決方案中有甚麼具體的差異。
模式為在一個脈絡、環境、上下文中常見的問題的解決方法,並且該解決方法是經過實踐可行的,而相較於 GOF 的設計模式,SOLID 與本文提到的 GRASP 能夠以更全面、更普遍的去解釋一個問題的解決方法,也能使我們辨認出真正的問題,而非表面現象。
通用職責分配軟體模式 (General Responsibility Assignment Software Patterns, GRASP)提供了一種職責在某些情境下該如何分配的模式。
GRASP怎麼實作?
GRASP 注重的是以及切入的角度是職責的分配,並且能透過 GRASP 去推導出每一種設計模式對於不同情境的解決方法是如何產生的。GRASP 有九個模式。
- 信息專家 : 如何進行職責的分配?
- 控制器 : 職責分配時,負責接收與協調(控制)來自 UI 層的訊息,以選擇對應的系統操作的第一個物件是哪個?
- 創造者 : 職責分配時,誰有職責創建物件 A?
- 高內聚 : 如何使系統、物件的交互容易理解與管理?
- 低耦合 : 如何減少不相干的元素間的互相影響?
- 防止變異 : 如何處理元素的不確定性、可擴展性?
- 多態 : 出現大量 if - else、switch ,並且在之後需要不斷更改其中的程式碼,要如何實作解決?
- 純虛構 : 依照信息專家分配後,仍有職責過多的問題,該如何處理?
- 間接性、中介 : 如何減少對物件 A 的依賴,從而達到靈活與低耦合?
以信息專家為主,高內聚、低耦合為輔,控制器、創造者、防止變異、多態、純虛構、中介為具體實現,GRASP 提供了一套層次不一的原則用以建構一個靈活易懂的系統。
獲得了什麼?

grasp的組合拳,圖片來源
靈活易懂的系統,或許太宏大了,用 GRASP 來解釋在開頭提到的工廠模式,過程會是這樣的。
- 高內聚 (High Cohsion) : 也就是一個物件當中的子元素,必須是彼此相關的並且物件應該是要關注他的職責,而不是創建邏輯,創建邏輯過長會導致模糊了關注點,因此必須將創建邏輯分離。
- 純虛構 (Pure Fabrication) : 依照純虛構,我們可以將這個創建的職責,憑空創建一個物件來負責,在這個語境下,該物件被稱為工廠,因為純虛構本身只負責一個職責,因此它是高內聚的。
- 低耦合 (Low Couping) : 也因為將創建邏輯分離出去,因此可以避免以下幾種麻煩,降低被創建物件與系統的耦合,達到重複利用的效果。
- 注入的物件多,將創建邏輯分離出去,可以達到被創建物件與注入物件的低耦合。
- 判斷條件複雜,通常判斷條件是與該物件被創建的情境有關,將判斷條件分離出去,可以達到情境與被注入物件的低耦合。
相信這一套組合拳下來,mentor 滿意的微笑、看不懂的其他人也會看傻的贊同。
作者心得
我的大四第一份實習時,mentor 一步一步的帶我完成了一個 ETL 的簡單 Project 後,就交給我一本大話設計模式,感覺很多人都看過這本,應該是中文講解設計模式很出名的一本書。
裡面透過一連串的故事,逐步的講解每個設計模式與運用的情境,很快就看完了,但就是覺得還是不太懂,在之後的實習過程,才發現了解一些更加普遍的背景知識之後,書裡面的內容都可以使用解數學方程式一般從問題推理出答案。
就像我在問題領域與解決方案領域提到的,只有瞭解了脈絡才能懂問題跟解決方案,因此只有瞭解了甚麼是物件導向、物件導向分析、更底層設計原理才能了解設計模式。