重構九式
{
第一式: 抽出方法
所有的重構, 都是從 Extract Method 開始, 當我們發現程式碼中有以下特徵:
1. 當一段程式碼需要寫註解特別解釋時.
2. 在 if else 內有一段邏輯時.
3. 在 switch case 內有一段邏輯時.
就可以使用第一式 Extract Method, 將一段程式碼重構成 method .
在 method 命名方面, 建議依照 名詞 + 動詞 的方式命名.
第二式: 抽出類別
物件導向程式碼最大的特點就是 class, 我們要將更相關的 method 放在同一個 class, 達到高內聚的目標.
重構第一式 Extract Method 時,我們特別以名詞 + 動詞的方式替 method 命名, 其中若名詞相同, 則表示這些 mehtod 的內聚性很高, 適合將這些 method 再透過重構第二式 Extract Class 重構到新的 class 內.
第三式: 將類別的長的一樣的程式碼抽出到超類
Extract Class 之後,雖然已經長出 class,但實務上會發現 method 內仍然有些程式碼是重複的, 根據 DRY 原則, 我們不希望有程式碼重複, 這會造成日後維護上的困難, 因為每次修改就得修改好幾份程式碼, 還可能遺漏修改而造成邏輯上的不一致.
對付 method 內重複的程式碼, 就必須使用重構第三式 Extract Superclass, 將重複的程式碼重構到 abstract class.
第四式: 將類別邏輯相同的部分抽出到超類
有時候會遇到一種程式碼, 並不是整塊重複, 而是外層重複, 內層卻不重複.
就必須使用重構第四式 Extract Closure, 將重複的的程式碼重構到 abstract class, 不重複的部分重構到 closure.
第五式: 類別的方法屬於同個職責, 此時應抽出介面建立職責(此時已達高階與低階相依於介面)
在 名詞 + 動詞 的 method 名稱部分, 名詞不同已經使用 Extract Class 解決, 剩下的是相同的動詞,也就是我們發現 3 個 class 都有相同的 method.
既然 3 個 class 的 method 都相同, 我們就可以使用重構第五式 Extract Interface, 更宏觀的角度, 將這 3 個 class 抽象化成一個相同的 interface.
第六式: 依賴注入 DI
經過 Extract Interface 之後, 我們已經將 3 個 class 抽象化成相同 interface, 理論上我們只需依賴 interface 即可, 但程式碼中卻還使用 switch case,並實際去 new 3 個 class, 也就是還實際依賴這 3 個 class.
實際依賴這 3 個 class 目前沒什麼大問題, 但只要將來有新的 class, 儘管也實踐相同 interface, 卻仍要繼續修改 swich case 去 new 新的 class, 這將造成維護上的負擔. 理想是將來無論新增任何 class 都不須修改程式碼, 這就必須使用重構第六式 Dependency Injection, 將 switch case 拿掉由外部注入物件, 達到低耦合的目標.
---(這之後無實作)--------
第七式: 將非垂直關係的共用邏輯, 套用組合的模式
重構一到六式,都是教我們的都是以垂直方式將 method 抽取到 class、abstract class、interface, 也就是其都有垂直的關係, 但某些 method 並沒有垂直的關係, 反而是跨 class 的水平關係.
就是說若是不屬於這個職責的範圍需求, 但實際每個商業邏輯類別又需要用到該功能, 此時應用組合的方式將這功能交由外部實做.
第八式與第九式 沒有領悟請參閱網站.
}
小試身手: (實作影片)
多多指教!! 歡迎交流!!
你不知道自己不知道,那你會以為你知道