單一職責原則(Single Responsibility Principle)簡稱SRP原則。
定義
應該有且僅有一個原因引起類的變更。
優點
可以降低類的複雜度,一個類隻負責一項職責,其邏輯肯定要比負責多項職責簡單的多;
提高類的可讀性,提高系統的可維護性;
變更引起的風險降低,變更是必然的,如果單一職責原則遵守的好,當修改一個功能時,可以顯著降低對其他功能的影響。
說明
單一職責原則不隻是面向對象程式設計思想所特有的,隻要是子產品化的程式設計,都适用單一職責原則;
單一職責原則要根據項目的實際情況去劃分職責粒度,職責粒度劃分太細容易引起職責擴散容易增加管理複雜度,職責粒度劃分太粗則容易增高變更引起的風險;
示例
背景
假設有一做産品的小公司,因為是創業階段,由于資金有限,公司機制不健全并且每個職工負責的職能較多,職工種類和職責配置設定如下表:
職工種類
職責分工
研發職工
需求分析,産品定義,産品設計,産品研發
銷售職工
産品銷售
假設公司由老闆親自驅動研發和銷售的職工進行運作,運作流程為産品需求分析->産品定義->産品設計->産品開發->産品銷售;
代碼
首先看普通的代碼實作:
執行結果:
李四進行産品需求分析
李四進行産品定義
李四進行産品設計
張三進行産品開發
王五進行産品銷售
分析
對于上述代碼,如果公司不斷發展要增加一類産品職員,用來負責産品的需求分析,産品定義和産品設計。那麼上述代碼應該如何應對需求變更?一般情況下的做法是先生成一個Staff類的ProductStaff子類,讓後讓ProductStaff子類實作研發職責接口IDevResponsibility中:
public void requirementsAnalysis(); //需求分析
public void productDefine(); //産品定義
public void productDesign(); //産品設計
然後空實作:
public void productDevelop(); //産品開發
最後在Boss類中去掉DevelopStaff的相關職責功能,然後增加新的ProductStaff對象替代DevelopStaff中去掉的職責,具體代碼如下:
運作結果:
修改該之後的代碼也能完成任務,可是代碼會變得晦澀難懂,此時的研發職工,仍然可以調用産品職工的相關職責,但是老闆需要知道這些不用再去調用了;而且在看ProductStaff類的時候會變得了解困難為什麼一個産品職工要實作研發職工的接口呢?
優化
鑒于以上問題,我們就需要對接口進行單一職責處理;首先将接口根據實際的分析進行職責粒度細化,本示例中,我們分析道可能會有一個産品職工種類出現,是以在接口設計階段把職責首先劃分為3類:産品職工職責,研發員工職責和銷售員工職責;
當變更發生時
此時的代碼将會顯得更加邏輯合理,更加便于維護;
總結
接口設計盡量按照單一職責原則進行設計
類設計盡量按照隻有一個原因引起類的變化進行設計
設計是有限度的,不能無限的考慮未來的情況
單一職責設計的前提是建立在客戶對使用對象有充分了解的情況下的,實際上為了提高了客戶的工作效率而增加了客戶的工作并且友善了自己的管理。