DRY原則 DRY 原則,它的英文描述為:Don’t Repeat Yourself。中文直譯為:不要重覆自己。也可以理解為:不要寫重覆的代碼。 我們從實現邏輯重覆、功能語義重覆和代碼執行重覆,這三種代碼重覆來說明DRY原則。 實現邏輯重覆 例如有兩個函數isValidUserName() 和 is ...
DRY原則
DRY 原則,它的英文描述為:Don’t Repeat Yourself。中文直譯為:不要重覆自己。也可以理解為:不要寫重覆的代碼。
我們從實現邏輯重覆、功能語義重覆和代碼執行重覆,這三種代碼重覆來說明DRY原則。
實現邏輯重覆
例如有兩個函數isValidUserName() 和 isValidPassword() ,它們的代碼其實是一樣的,這個時候如果我們將其合併成一個函數,雖然代碼量減少了,也沒有重覆代碼,但卻違反了DRY原則,從代碼實現邏輯上看起來是重覆的,但是從語義上並不重覆。所謂“語義不重覆”指的是:從功能上來看,這兩個函數乾的是完全不重覆的兩件事情,一個是校驗用戶名,另一個是校驗密碼,其實兩個代碼是做不同的事情,如果因為代碼一樣合併了,後面由於用戶名或者密碼校驗邏輯改變,都將使函數再次拆分成兩個函數。
功能語義重覆
現在我們再來看另外一個例子。在同一個項目代碼中有下麵兩個函數:isValidIp() 和 checkIfIpValid()。儘管兩個函數的命名不同,實現邏輯不同,但功能是相同的,都是用來判定 IP 地址是否合法的。儘管兩段代碼的實現邏輯不重覆,但語義重覆,也就是功能重覆,我們認為它違反了 DRY 原則。而且如果兩個函數功能一樣同時存在,且都被調用,這時一個程式員如果只知道一個函數,並修改了其函數邏輯,那麼會導致另一個函數的邏輯並沒有改變,偶從遺漏修改。
代碼執行重覆
這段代碼,既沒有邏輯重覆,也沒有語義重覆,但仍然違反了 DRY 原則。這是因為代碼中存在“執行重覆”。
重覆執行最明顯的一個地方,就是在 login() 函數中,email 的校驗邏輯被執行了兩次。一次是在調用 checkIfUserExisted() 函數的時候,另一次是調用 getUserByEmail() 函數的時候。這個問題解決起來比較簡單,我們只需要將校驗邏輯從 UserRepo 中移除,統一放到 UserService 中就可以了。
除此之外,代碼中還有一處比較隱蔽的執行重覆,不知道你發現了沒有?實際上,login() 函數並不需要調用 checkIfUserExisted() 函數,只需要調用一次 getUserByEmail() 函數,從資料庫中獲取到用戶的 email、password 等信息,然後跟用戶輸入的 email、password 信息做對比,依次判斷是否登錄成功。實際上,這樣的優化是很有必要的。因為 checkIfUserExisted() 函數和 getUserByEmail() 函數都需要查詢資料庫,而資料庫這類的 I/O 操作是比較耗時的。我們在寫代碼的時候,應當儘量減少這類 I/O 操作。
如何提高代碼可復用性
提高代碼可復用性的一些方法,有以下 7 點。
- 減少代碼耦合
- 滿足單一職責原則
- 模塊化
- 業務與非業務邏輯分離
- 通用代碼下沉
- 繼承、多態、抽象、封裝
- 應用模板等設計模式