1.背景
單一職責原則(SRP:Single responsibility principle)又稱單一功能原則,面向對象五個基本原則(SOLID)之一。它規定一個類應該只有一個發生變化的原因。該原則由羅伯特·C·馬丁(Robert C. Martin)于《敏捷軟件開發:原則、模式與實踐》一書中給出的。馬丁表示此原則是基于湯姆·狄馬克(Tom DeMarco)和Meilir Page-Jones的著作中的內聚性原則發展出的。
2.概念
就一個類而言,應該僅有一個引起它變化的原因。應該只有一個職責。每一個職責都是變化的一個軸線,如果一個類有一個以上的職責,這些職責就耦合在了一起。這會導致脆弱的設計。當一個職責發生變化時,可能會影響其它的職責。另外,多個職責耦合在一起,會影響復用性。此原則的核心就是解耦和增強內聚性。
通俗的講:
方法級別的單一職責原則:一個方法只負責一件事
類級別的單一職責原則: 一個類只負責一件事
類庫級別的單一職責原則:一個類庫應該職責清晰
項目級別的單一職責原則:一個項目應該職責清晰(客戶端、管理后臺、后臺服務、任務調度服務、分布式引擎)
系統級別的單一職責原則:為通用功能拆分子系統(日志系統、權限系統、存儲系統)
3.針對的場景
有一個類T負責兩個不同的職責:職責P1和職責P2。當因為職責P1的需求發生改變而需要修改類T的時候,有可能會導致原本運行正常的職責P2功能發生故障。
舉例:下面示例中一個圖片加載類負責3個不同的職責:圖片下載、保存到緩存、圖片顯示
public class ImageLoader {/*** 下載*/public Bitmap download(String url){Bitmap bitmap = null;// 下載圖片//...return bitmap;}public void displayImage2(ImageView imageView, String url){Bitmap bitmap = download(url);// 圖片顯示//...// 圖片緩存imageCache(bitmap);}public void imageCache(Bitmap bitmap){// 圖片緩存//...}
}
4.解決方案
遵循單一職責原則,分別建立兩個類T1、T2,使T1完成職責P1功能,T2完成職責P2功能。這樣,當修改類T1的時候,不會使職責P2發生故障風險。同理,當修改T2的時候,也不會使職責P1發生故障風險。
舉例:針對上面案例中的代碼,我們進行優化,我們把圖片下載、保存到緩存、圖片顯示這幾個職責定義成單獨類,而不是一個類全搞定。
/*** 下載類*/
public class Download {/*** 下載** @param url 下載地址* @return 圖片*/public Bitmap download(String url) {Bitmap bitmap = null;System.out.println("下載圖片");return bitmap;}
}
/*** 緩存類*/
public class Cache {/*** 緩存圖片* @param bitmap 圖片*/public void imageCache(Bitmap bitmap){System.out.println("緩存圖片");}
}
/*** 圖片加載類*/
public class ImageLoader {/*** 3加載圖片* @param imageView 圖片控件* @param url 圖片地址*/public void displayImage3(ImageView imageView, String url){Download download = new Download();Bitmap bitmap = download.download(url);// 圖片顯示System.out.println("顯示圖片");//...// 圖片緩存Cache cache = new Cache();cache.imageCache(bitmap);}
}
5.優點
-
降低類的復雜度,一個類只負責一個職責。
-
提高類的可讀性,提高系統的可維護性。
-
降低變更引起的風險。變更是必然的,如果單一職責原則遵守得好,就可以達到職責/功能的解耦。