單一職責原則是面向對象原則五大原則中最簡單,也是最重要的一個原則, 他的字面定義如下: 單一職責原則(Single Responsibility Principle, SRP): 一個類只負責一個功能領域中的相應職責,或者可以定義為:就一個類而言,應該只有一個引起它變化的原因。 從定義中可以看出在定 ...
單一職責原則是面向對象原則五大原則中最簡單,也是最重要的一個原則, 他的字面定義如下:
單一職責原則(Single Responsibility Principle, SRP): 一個類只負責一個功能領域中的相應職責,或者可以定義為:就一個類而言,應該只有一個引起它變化的原因。
從定義中可以看出在定義類的時候要將職責劃分清楚, 不能讓一個類負責乾多個事情。換句話說就是一個類只有一個引起他變化的點。如果一個類負責乾多個事情那麼就會有多個引起他變化的原因。那麼這個類就不穩定了,這個類就容易變化,因為我們知道如果乾的事情越少變化的誘因就愈少,如果乾的事情越多變化的誘因就愈多。變化的越多引起bug的可能性就越大, 最終就會影響到你設計的系統容易出現bug,反之系統出現bug的肯能性就越小。
現在我們有這麼一個場景,對人員信息的維護, 通常對用資料庫的操作如下:
public class Employee { public int Id { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public int Age { get; set; } public DateTime BirthDay { get; set; } } public class EmployeeRepository { public void Create(Employee employee) { DataBase<Employee> dataBase = new DataBase<Employee>(); dataBase.Create(employee); } public IEnumerable<Employee> Query() { DataBase<Employee> dataBase = new DataBase<Employee>(); return dataBase.Query(); } }
咋一看這個設計似乎是沒有問題的,但是在看看我們剛剛講的那個原則,其實這個設計已經違背了我麽的SRP原則,主要是EmployeeRepository 類的職責太多,它包含的兩個方法,一個是給資料庫中創建數據一個是查詢數據,從這個拆分粒度上來說是EmployeeRepository 承擔了兩個職責。 因此我們因該將他拆分開來如下:
public class EmployeeRepository { public void Create(Employee employee) { DataBase<Employee> dataBase = new DataBase<Employee>(); dataBase.Create(employee); } } public class EmployeeQuery { public IEnumerable<Employee> Query() { DataBase<Employee> dataBase = new DataBase<Employee>(); return dataBase.Query(); } }
這樣我們就將原來的EmployeeRepository中的查詢數據的職責拆分到EmployeeQuery類中,這樣EmployeeRepository就只負責對數據的"寫"操作而EmployeeQuery 只負責對數據"讀"操作, 這就回到了電腦的本質上來了, 即電腦的本質就是 "讀寫".
寫到這裡就應該告一段落了, 但是我想很多人都會說第一個EmployeeRepository 的職責劃分的也可以啊,只負責數據的操作啊, 其實這個問題也沒有錯, SRP原則本身就是一個充滿爭議的原則, 每個人對類的組織不同,職責的劃分不同, 系統的規模不同對SRP使用也是不同, 對SRP的把握粒度也不同,這要根據具體問題具體對待.