此系列文章是我閱讀《Refactoring To Patterns》過程中實際演練的筆記。閱讀過程中發現若沒有相當的 Design Patterns、Refactoring 底子,此書真的不易閱讀,必須伴隨實際操作才能更理解每個步驟具體的方式,故在這記錄之餘也跟各位分享。
書中是使用 Java 的程式碼作為範例,而我比較熟稔 C#,所使用的演練環境為:Visual Studio 2017、ReSharper、VsVim。過程中會因應 ReSharper 的功能,所以有些許的調整以便更「優雅」的進行重構。
此篇是關於 7.4 Replace State-Altering Conditionals with State 的具體演練。
此次的 smaple code 是我建立的,若有錯誤還請多包涵,詳細程式碼請見:https://github.com/mystic01/refactoringtopatterns。
![]() |
![]() |
![]() |
以下,請搭配影片閱讀(數字表示影片時間、藍色表示重構技法、紫色表示我的困擾):
- 將兩個條件式給抽出為 method,提高可讀性。Extract Method。0:00
- 將
state的型態由string改為PermissionState。1:18- 一樣使用先用再生的技巧,改掉
string為PermissionState,再將其生出。 - 接著逐一改為
new PermissionState("XXX"),這邊用了一個小技巧。2:10
先把建構子妥妥的生出來,接著逐一半自動的改為new PermissionState("XXX")。 - 把該改的
string都半自動的換為PermissionState。
- 一樣使用先用再生的技巧,改掉
- 將各個
static的PermissionState換為對應的 class。4:00
這邊好像沒有什麼特別的技巧,就逐一改改生生...。
- 將各個
static的PermissionState搬移(Move To Another Type)到PermissionState。6:45
- 搬
claimBy()至所有PermissionState(含其子 class)。7:36- 因為
claimBy()這個 method 要保留在SystemPermission中,所以將其內容抽出為claimBy2()(避免名稱重複)。 - 將
claimBy2()搬移(Move Instance Method)至PermissionState。
※ 7:50 這邊有一個極度困擾我的問題,希望有大師可以為我解惑,感激不盡。
只要使用 Move Instance Method,被抽出去 method 所用到的 field 就會再被 Encapsulate 一次。就像影片中,又產出了一個State1的 property,但明明就有State存在。這個問題後面的步驟還會陸續發生,讓我非常困擾,也 Google 不到解法。
※ 8:26 困擾之餘,也借影片分享將兩個 Property 改回同一個的方式。硬是將State1rename 為State是行不通的(會發生衝突,導致呼叫端還是會保留在State1)。我是先把State改為StateXXXX(非rename),再把State2rename 為State,此時就不會發生衝突,接著刪掉其中一個State。如果有更好的方式也請告訴我,希望可以忽略衝突強制 rename...。
- 將
claimBy2()改名回claimBy()。 - 將 claimBy() 移到(Push Members Down)該放置的子 class(兩個 Requested 相關 class)。Push Members 的動作就帶有複製的意思,超棒的。
- 跳至錯誤處,半自動的在
PermissionState生出abstract的claimBy()。 - 逐一跳至錯誤處,逐一處理 override、implement
claimBy(),也同時刪除不必要的判斷邏輯。
- 因為
- 仿照上述
claimBy()的方式依序處理grantBy()、denideBy()。10:57
- 整理程式,將各 class 搬移至各檔案,打完收工!!18:40
其他 Refacotirng To Patterns 影片請見:Refactoring To Patterns
不堪入目的練功過程:Refactoring To Patterns (exercise)



