本筆記除了以文字說明SOLID設計原則以外,並以Java code實際舉例。
Single Responsibility Principle (SRP) 單一職責原則 - 每個人負責屬於自己的職責,不該承擔太多職責,大家各自做自己應該做的事情,且不會互相干擾。
以下舉例說明,假設有個Employee類別,calculatePay()用來計算薪資,是屬於會計部的需求,genHoursReport()用來產生工時報表,是屬於人資部的需求。
calculateWorkingHours() 用來計算工時,calculatePay()與genHoursReport() 方法都依賴這個方法,也就是無論是計算薪資或是產生工時報表,都需要先計算出工時。
假設會計部門要求要更改計算薪資的方式,需要動到計算工時的邏輯calculateWorkingHours(),由於產生工時報表的方法也會呼叫這個method來計算工時,因此這個修改有可能會導致工時報表錯誤的問題,也就是為了會計部門的需求更動,會影響到人資部門的需求功能。
因此問題就浮現了,Employee class做太多事情了,把其他人的職責也囊括進來這邊,會計部門的需求改變會影響到人資部門的功能,這就不符合SRP了。
因此,需要把不同的職責拆分到不同的類別,以免互相影響:
如此將會計的計算薪資與人資的工時報表拆開為獨自的類別(將不同的責任方法拆分到不同的類別),內部有各自的計算工時邏輯,互不影響。會計部門的計算工時邏輯更動,不會影響人資部門的功能了。
Open/Closed Principle (OCP) 開放封閉原則 - 「對擴充開放,對修改封閉」: 需求變動時,可以對既有的程式碼進行擴展,而不須修改原有的程式碼。
續上程式碼,修改如下:
要根據不同角色計算薪資,這樣的程式碼,每當有一個新的role就要去改switch的code,增加一個case與對應的method,來計算對應的薪資,如此就違反OCP原則了,要擴展不應該要去改原本的程式碼。
因此為了符合OCP原則,我們修改一下code:
如此修改,日後若要擴充新的Role,只需新增一個XXXRole class,並且定義calcSalary()方法,將薪資計算邏輯寫在這,就完成了。擴充功能完全不需要動到原本的code,即符合OCP原則。