被誤解的單一職責原則 - Joe
谷歌工程主管喬·林奇的文章,獲得SOLID原則作者鮑勃大叔點贊轉發的文章:
作者推薦將SRP視為DDD原則的自然結果:跨DDD限制上下文共享的模型是不安全的。
單一職責原則 (SRP) 是SOLID設計原則中的第一個,自 2000 年由羅伯特·馬丁(“鮑勃大叔”)引入以來,它們在軟體工程中產生了極大的影響。不幸的是,這一特定原則經常被誤解。再加上盲目的信念,這可能會導致過於簡單化的思維和設計錯誤。
該原則經常被定義為“每個軟體模組都應該有一個且只有一個改變的理由”。然後這個名字似乎暗示該模組應該有一個“單一的責任”。這似乎很容易理解。所以模組應該只做一件事,對吧?
不對!
有一個另外不同的經驗法則:一個函式才應該只做一件事:您是否曾經在命名諸如“ImportData And LoadIntoDatabase”之類的函式時捂住鼻子。我們知道這一點:一個函式應該有一個單個功能。
SRP單一職責是保證凝聚力(banq:包含的職責功能越多,凝聚力越弱;單一的職責能提高凝聚力 =>高凝聚低耦合)
該原則實際上意味著給定模組中的程式碼必須由一個且只有一個最終業務所有者(或功能單元)擁有。如果這不是真的,你必須打破它。
Bob 大叔舉了一個例子(書面和談話),其中 CFO 和 COO 都依賴於計算員工工時的程式碼:其中一位高管要求更改該程式碼,但這違反了另一位高管所在部門的業務規則,因此工時計算是不能共享的,這樣這段程式碼應該有一個CFO財務版本和一個COO運營版本,儘管這違反了我們的DRY 和凝聚力的敏感性。
這與我看到的大多數人應用 SRP 的方式非常不同。
雖然我不需要每天都應用它,但 SRP 確實符合我的經驗:
我在運輸管理系統上工作,我們有一個代表卡車運動的物件。它本質上是可操作的——您可以指定司機、送貨地點的到達和離開時間等。該物件的另一個版本用於支付司機的費用。這些物件是一對一的,有很多明顯的重複。它真的把我逼瘋了!有幾次我試圖用相同的程式碼統一對待它們,但它不可避免地失敗了。你猜怎麼著?一個物件屬於運營,一個屬於(你猜對了)財務。 這正是鮑勃叔叔所說的。 雖然 SRP 是正確的,但有時很難主動應用,因為誰(或哪個組)是某事的“最終所有者”可能很模糊並且需要時間才能變得清晰,尤其是如果您正在與許多利益相關者一起從頭開始構建系統。
從另一個角度來看,我將 SRP 視為DDD原則的自然結果:擁有跨有界上下文共享的模型是不安全的。
世面上錯誤解釋單一職責SRP
不幸的是,我看到很多人盲目地遵循對 SRP 的錯誤理解。通常喜歡小型“類”的人會用它來證明製作更多甚至更小類的理由。
一開始是一個簡單、易於理解的類,最終被分解成許多現在從集合集體級別上很難理解的抽象(banq注:太瑣碎,一地雞毛,程式碼小類的數量太多了)。
無論您是否喜歡這種風格,SRP 本身都不會是這個意思。
我最近閱讀了自適應程式碼(第 2 版,Microsoft Press),截至今天,在亞馬遜上的評分為 4.7/5,評分為 123:SRP 有一整章。在整個過程中,它錯誤地將 SRP 解釋為與做太多事情的類有關,並僅以此證明設計決策的合理性。
出於凝聚力的原因,類確實不應該做太多事情;所以設計決策並不總是糟糕的。
但是,作為一個例子,一個有 2 頁程式碼的類被分解為大約 12 個類和介面(類的數量太多),所有這些都以被誤解的 SRP 的名義。
這是一本由一位有成就的作者所著的受人尊敬的書,而不是一些隨意的部落格文章。
SRP起源
我們必須鼓勵新的工程師理解這些原則背後的推理,與它們搏鬥,在它們有意義時應用它們,在它們沒有意義時拒絕它們。
研究回到源頭也是很有啟發和吸引力的。
SOLID原則植根於早於我們這一代的核心設計原則:比如介紹資訊隱藏概念的Parnas論文和Constantine介紹耦合和內聚概念的那本書。
鮑勃大叔認為這些作品影響了他的思維。 在他的演講中,通常在他必要的、隨機的物理學漫談之後,他總是努力將現在和過去聯絡起來。 這是一個偉大的事情。
但是,我們周圍並沒有很多鮑勃大叔。 作為一個行業,我們並沒有很好地將經驗代代相傳。 我們能做些什麼呢?
雖然說 "太陽底下沒有新鮮事 "是一種誇張的說法,但令人驚訝的是,我們經常與老問題搏鬥,卻沒有意識到我們可以站在前人的肩膀上。
從無界從有界
為什麼我們作為工程師會喜歡這些設計原則呢?(我知道我喜歡。)除了它們的啟發式效用之外,我認為這是因為它們為本來是無邊界的解決方案空間提供了感覺上的約束。
它們減少了焦慮,並在無法確定的地方引入了一些可以確定的東西。
通常情況下,我們是一個叛逆的群體,討厭約束(告訴別人他們必須使用vim或emacs)。 但是,當我們面對一個開放性問題的深淵時,約束是我們的朋友(banq注:當你凝視深淵時,深淵也在凝視你,你不至於成為深淵的原因是你能約束自己)。
基於經驗的觀察變成了原則,變成了經驗法則,變成了正式的規則,最後僵化成法律。(banq注:道可道非常道,名可名非常名,讀書的人基本是教條主義與自以為是者)
因此,在這裡我們要小心!
撇開物理學不談,我在軟體工程中發現的唯一絕對規律是沒有規律可尋!(banq注:一切可變,唯一不變的是變化) 畢竟,我們是在用位元位元組建造城堡。
相關文章
- 單一職責原則詳解
- 單一職責原則
- 設計原則之【單一職責原則】
- 單一職責原則筆記筆記
- 一 :SRP(單一職責原則)
- 物件導向設計原則之單一職責原則物件
- 單一職責原則在 iOS 中的應用iOS
- [譯] 更可靠的 React 元件:單一職責原則React元件
- 設計模式六大原則(一)----單一職責原則設計模式
- 編碼最佳實踐——單一職責原則
- 設計模式的七大原則(1) --單一職責原則設計模式
- 設計模式六大原則(1):單一職責原則設計模式
- 面象物件設計6大原則之一:單一職責原則物件
- 小話設計模式原則之(2):單一職責原則SRP設計模式
- 嘻哈說:設計模式之單一職責原則設計模式
- 單一職責原則:軟體世界中最重要的規則 - DZone
- 《JavaScript設計模式與開發實踐》原則篇(1)—— 單一職責原則JavaScript設計模式
- 吃透單一職責原則,100倍效果提升程式碼質量
- [OOD] 為什麼單一職責原則(SRP)是最難運用的
- 將單一職責原則應用於前端FE/BFF分層架構 - Expedia前端架構
- 設計模式筆記:單一職責原則(SRP, Single Responsibility Principle)設計模式筆記
- 領域知識與SOLID單一責任原則的解釋Solid
- Laravel深入學習8 – 單一責任原則Laravel
- 設計模式 - 單一職責設計模式
- 流程、規則和管理職責
- 重構 - 保持函式的單一職責函式
- 一起玩轉微服務(7)——單一職責微服務
- 物件的責任與職責物件
- 【原創】《Oracle DBA日常工作和職責》Oracle
- 簡單介紹Python 處理錯誤的原則Python
- 23種設計模式(六)單一職責之橋模式設計模式
- 增刪改是Respository的職責,還是Entity的職責?
- Oracle DBA的職責Oracle
- DRY原則的一個簡單實踐
- 電商架構設計-通過系統和業務拆分,遵循單一職責原則SRP,保障整個系統的可用性和穩定性架構
- 職責鏈模式的一篇文章模式
- 客戶程式的職責
- 前端架構的職責前端架構