[RefactoringToPatterns] 8.3 Replace One/Many Distinctions With Composite

此系列文章是我閱讀《Refactoring To Patterns》過程中實際演練的筆記。閱讀過程中發現若沒有相當的 Design Patterns、Refactoring 底子,此書真的不易閱讀,必須伴隨實際操作才能更理解每個步驟具體的方式,故在這記錄之餘也跟各位分享。

書中是使用 Java 的程式碼作為範例,而我比較熟稔 C#,所使用的演練環境為:Visual Studio 2017、ReSharper、VsVim。過程中會因應 ReSharper 的功能,所以有些許的調整以便更「優雅」的進行重構。

此篇是關於 8.3 Replace One/Many Distinctions With Composite 的具體演練。

此次的 smaple code 是我建立的,若有錯誤還請多包涵,詳細程式碼請見:https://github.com/mystic01/refactoringtopatterns

終於又出現一個章節,書中有比較詳盡的描述程式碼、單元測試,這次重構起來比較有感。

以下,請搭配影片閱讀(數字表示影片時間、藍色表示重構技法、紫色表示我的困擾):

  1. 建立 CompositeSpec,以因應未來各種複合式的 Spec0:00
    1. 和之前重構的技巧一樣,「先用再生」,絕對不要傻傻的手動建立 CompositeSpec
       
  2. selectBy(List<Spec> specs) 中部份邏輯抽至 CompositeSpec 裡。2:24
    1. 將部份邏輯抽取為 isSatisfiedBy()Extract Method)。
    2. 發現 isSatisfiedBy() 中具有依戀情節(Feature Envy),處理的完全是 CompositeSpec 的職責。故將其搬移至 CompositeSpecMove Instance Method)。
  3. selectBy(List<Spec> specs) 用 selectBy(Spec spec) 取代。3:54
    1. 使 selectBy(List<Spec> specs) 透過呼叫 selectBy(Spec spec) 完成。此時必須使 CompositeSpec 繼承 Spec 才能通過編譯。
    2. 去除 selectBy(List<Spec> specs),呼叫端改用 selectBy(new CompositeSpec(specs))
       在這修改過程中(5:49), IDE 會自動變為selectBy(new CompositeSpec(specs))specs),必須再手動刪除後頭的 specs ,有點困擾啊,不知道有沒有更棒的方式。8:20 也發生了一次。
       
  4.  整理 CompositeSpec6:14
    1. ComposietSpec 當中的 Spec 改為逐一 Add,而非於建構子當中傳入。
    2. getSpecs() 所回傳的 List<Spec> 改為 ReadOnlyCollection<Spec> 型態。

搞定!

其他 Refacotirng To Patterns 影片請見:Refactoring To Patterns
不堪入目的練功過程:Refactoring To Patterns (exercise)