218
技術社區[雲棲]
連載:麵向對象葵花寶典:思想、技巧與實踐(30) - SRP原則
前麵詳細闡述了“高內聚低耦合”的總體設計原則,但如何讓設計滿足這個原則,並不是一件簡單的事情,幸好各位前輩和大牛已經幫我們歸納總結出來了,這就是“設計原則”和“設計模式”。毫不誇張的說,隻要你吃透這些原則和模式並熟練應用,就能夠做出很好的設計。
==================================================================
【SRP原則詳解】
SRP,single responsibility principle,中文翻譯為“單一職責原則”!
這是麵向對象類設計的第一個原則,也是看起來最簡單的一個原則,但這實際上遠遠沒有那麼簡單,很多人都不一定真正理解了!
我們隨便找幾個網上的解釋,看看各位大師或者經典網站是如何解釋的:
百度百科(https://baike.baidu.com/view/1545205.htm):
一個類應該有且僅有一個職責。關於職責的含意,麵向對象大師Robert.C.Martin有一個著名的定義:所謂一個類的職責是指引起該類變化的原因,如果一個類具有一個以上的職責,那麼就會有多個不同的原因引起該類變化,其實就是耦合了多個互不相關的職責,就會降低這個類的內聚性。 |
說句實話,雖然是麵向對象大師Martin的解釋,我還是看得不甚明白:引起類變化的原因太多了,例如:
給類加一個方法是變化吧?
給類加一個屬性是變化吧?
類的函數增加一個參數是變化吧?
。。。。。。
引起這些變化的原因太多了,如果每個原因都是一個職責,那SRP原則簡直就沒法判斷了!
Wiki百科(https://en.wikipedia.org/wiki/Single_responsibility_principle )內容和百度百科基本一致,看起來百度百科像wiki百科的翻譯:)
Martin defines a responsibility as a reason to change, and concludes that a class or module should have one, and only one, reason to change. |
除了這些標準的解釋外,還有一種說法:SRP就是指每個類隻做一件事!
這個解釋更通俗易懂,也更加適合中國人理解。雖然比Martin大師的解釋更清楚一些,但仔細想想,還是有個地方比較難以理解:什麼叫做“一件事”?
比如說一個學生信息管理類,這個類有“添加學生信息”、“查詢學生信息”、“修改學生信息”、“刪除學生信息”,那麼這是4件事情,還是一件事情呢?
看起來好像是4個事情,但稍有經驗的朋友應該都知道,這4個事情絕大部分情況下都是一個類來實現的,而不是分成4個類!
所以關鍵的問題在於:什麼是“一件事”?是每個功能一件事情麼?
其實答案就在我們自己身上,因為隻要我們工作,無時不刻的承擔著一定的“職責”!
現在讓我們拋開麵向對象,拋開軟件,拋開計算機,來看看我們自己的“職責”。
比如說,我是一個程序猿,我的職責應該是“寫程序”,但寫程序有很多事情,例如:編碼,單元測試、係統測試,bug修複,開會,寫文檔。。。。。。
再比如說,我的BOSS是一個管理者,他的職責是“管理程序猿”,他也有很多工作,例如:製定計劃,團隊建設、開會、協調資源、寫文檔。。。。。。
又比如說,我是一個快遞員,也有很多工作:分包、快遞、收款、開會。。。。。。
這些職責其實都不是我們自己定義的,而是公司或者部門或者組織給我們安排工作的時候定義的,也就是說:“職責”是站在他人的角度來定義的,而不是自己定義的,也許你想把自己定義成CEO,但你的老板會真的讓你當CEO麼?
經過對我們自己的職責的分析,我們可以得出兩個關於職責的重要結論:
1) 職責是站在他人的角度來定義的
2) 職責不是一件事,而是很多事情,但這些事情都是和職責緊密相關的
對應到麵向對象設計領域,我們可以說一個類的職責應該如下定義:
1) 類的職責是站在其它類的角度來定義的;
2) 類的職責包含多個相關功能;
因此,SRP可以翻譯成“一個類隻負責一組相關的事情”,對應到代碼中就是:一個類有多個方法,這些方法是相關的。
當然,如果你再讓我解釋什麼是“相關”,那我隻能吐血了:)
有了這個定義,我們再來看“學生信息管理類”,很明顯,學生管理類具有的4個功能都是和“管理”相關的,按照SRP原則,應該隻設計一個“學生信息管理類”就可以了。
【SRP原則範圍】
但現實世界往往比理想要複雜,一個最典型的例子就是“辦公一體機”。
根據SRP原則,打印機可以設計成一個類,複印機也可以設計成一個類,掃描儀也可以設計成一個類,傳真機還是可以設計成一個類,但偏偏就是出了個“辦公一體機”,這個機器集成了“打印、複印、掃描、傳真”4個職責!
如果我們要設計一個“辦公一體機”的類,怎麼也不可能設計出一個符合SRP原則的“辦公一體機”的類來!
怎麼辦?是SRP不正確麼,還是我們永遠都不要設計“辦公一體機”這樣的類?
其實SRP也沒有錯,“辦公一體機”也應該設計,但:不要用SRP來約束“辦公一體機”這樣的類!
也就是說,SRP其實是有適應範圍的,SRP隻適合那些基礎類,而不適合基於基礎類構建複雜的聚合類。
在“辦公一體機“的樣例中,“打印機”、“複印機”、“掃描儀”、“傳真機”都是基礎類,每個類都承擔一個職責,而辦公一體機是“聚合類”,同時集成了4種功能!
細心的朋友可能會繼續問道:SRP不能應用於聚合類,那麼如何保證聚合類的設計質量呢?
這個問題的答案在GoF的《設計模式》一書中有詳細的答案,即:優先使用對象組合,而不是類繼承。詳細內容請參考後續“設計模式”部分的內容
================================================
轉載請注明出處:https://blog.csdn.net/yunhua_lee/article/details/25279539
================================================
最後更新:2017-04-03 12:56:35