Robert C. Martin (Uncle Bob)
良好設計的基礎原則#
將因相同原因而變動的東西聚集在一起,將因不同原因而變動的東西分開。
這個原則通常被稱為單一職責原則(Single Responsibility Principle, SRP)。簡言之,一個子系統、模組、類別甚至函式,都不應該有超過一個需要變動的理由。
經典的反面教材#
一個典型的例子是一個處理商業邏輯、報表和資料庫的類別:
public class Employee {
public Money calculatePay() ...
public String reportHours() ...
public void save() ...
}有些程式設計師可能認為把這三個功能放在一起完全合理——畢竟類別本來就是操作共同變數的函式集合。然而問題在於,這三個函式因完全不同的原因而改變:
calculatePay隨商業規則改變而改變reportHours隨報表格式需求改變而改變save隨 DBA 調整資料庫結構而改變
這三個變動原因的結合使得 Employee 非常不穩定。更重要的是,任何依賴 Employee 的類別都會受到這些變動的影響。
正確的分離方式#
將職責分離到不同的類別中:
public class Employee {
public Money calculatePay() ...
}
public class EmployeeReporter {
public String reportHours(Employee e) ...
}
public class EmployeeRepository {
public void save(Employee e) ...
}每個類別可以放入各自的元件中——報表相關類別進入報表元件、資料庫相關類別進入 repository 元件、商業規則進入商業邏輯元件。這些類別可以獨立修改和獨立部署,任何一個的修改都不會強迫其他元件重新編譯或重新部署。
依賴反轉的進一步可能#
雖然上述方案中
Employee仍然被其他類別依賴,但透過**依賴反轉原則(Dependency Inversion Principle, DIP)**的運用,甚至Employee本身也可以獨立修改和部署——但那是另一本書的主題了。
謹慎運用 SRP,將因不同原因而變動的東西分開,是打造具有獨立可部署元件結構設計的關鍵之一。