單一職責
單一職責原則(Single Responsibility Principle, SRP):一個類只負責一個功能領域中的相應職責,或者可以定義為:就一個類而言,應該只有一個引起它變化的原因。
單一職責原則是實現高內聚、低耦合的指導方針,它是最簡單但又最難運用的原則
單一職責原則是最簡單的物件導向設計原則,它用於控制類的粒度大小
設計原則很重要的一點就是簡單,單一職責,也就是我們經常所說的專人幹專事。
一個單元(一個類、函式或者微服務)應該有且只有一個職責。無論如何,一個微服務不應該包含多於一個的職責。職責單一的後果之一就是職責單位(微服務,類,介面,函式)的數量劇增。據說Amazon,Netflix這些採用微服務架構的網站一個小功能就會呼叫幾十上百個微服務。但是相較於每個函式都是多個業務邏輯或職責功能的混合體的情況,維護成本還是低很多的。 SRP中的“單一職責”是個比較模糊的概念。對於函式,它可能指單一的功能,不涉及複雜邏輯;但對於類或者介面,它可能是指對單一物件的操作,也可能是指對該物件單一屬性的操作。總而言之,單一職責原則就是為了讓程式碼邏輯更加清晰,可維護性更好,定位問題更快的一種設計原則。
什麼是高內聚低耦合?
這犀利的措辭一看就是來自開發界的術語。高內聚是說一個功能模組最好僅完成一個獨立的子功能並且完成的很好。低耦合是指模組與模組之間儘量獨立/聯絡少/介面簡單。
這個原則出現的背景是為了讓程式“可複用/可擴充套件/夠靈活/可維護”。幹過一陣子產品的人對這幾個詞應該都不陌生。對於程式設計者來說,這幾個詞是十分重要的,不亞於產品經理口中的“使用者體驗”(原則or擋箭牌)。
優點
單一職責的優點如下:
•類的複雜性降低,實現什麼職責都有清晰明確的定義。•可讀性提高,複雜性降低。•可維護性提高,可讀性提高。•變更引起的風險降低,變更是必不可少的,如果介面的單一職責做得好,一個介面修改只對相應的實現類有影響,對其他的介面無影響,這對系統的擴充套件性、維護性都有非常大的幫助。
記得在三字經裡邊有這樣一段 教之道,貴以專(出自三字經) 說的就是無論學習還是構建團隊,最重要的是專才,而不是全才。就好比一個足球隊,如果都是前鋒或者都是後衛,那麼這樣的球隊一定不能出成績,反而是將各個位置上的人進行統一協調,根據分工不同,共同協作,形成1+1>2的效果,那麼這樣的團隊就非常容易出成績。
有很多公司為了趕進度,經常會招聘一些所謂的全能型人才,但是這種人往往專業的程度不夠,當遇到某些棘手的問題的時候,往往不能夠非常快速的解決問題。從而導致最終交付的質量較差。
單一職責的目的
實施單一職責的目的如下:
•以類來隔離需求功能點,這樣當一個點的需求發生變化的時候,不會影響別的類的邏輯,這個和設計模式中的開閉原則類似,對於擴充套件持開放態度,對於修改持關閉態度。•是一個原子模組級的粒度,至於原子的粒度到底是什麼樣的,應該因業務而異,設計的過程中同時考慮業務的擴充套件,所以這就要求在設計的過程中,必須有業務專家共同參與,共同規避風險。•粒度小,靈活,複用性強,方便更高一級別的抽象。
每個微服務單獨執行在獨立的程式中,能夠實現鬆耦合,並且獨立部署。
如何做
分3步:
1.把一個具體的問題抽象成一類問題;
2.根據使用者體驗流程劃分功能模組;
3.針對每個功能設計封閉的解決方案。
最佳實踐
在實際工作中,有一個經常會用到的設計模式,DAO模式,又叫資料訪問物件,裡面定義了資料庫中表的增、刪、改、查操作,按照單一職責原則,為什麼不把增、刪、改、查分別定義成四種介面?這是因為資料庫的表操作,基本上就是這四種型別,不可能變化,所以沒有必要分開定義,反而經常變化的是資料庫的表結構,表結構一變,這四種操作都要跟著變。所以通常我們會針對一張表實現一個DAO,一張表就代表一種型別的職責。