此系列文章是我閱讀《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。
終於又出現一個章節,書中有比較詳盡的描述程式碼、單元測試,這次重構起來比較有感。
以下,請搭配影片閱讀(數字表示影片時間、藍色表示重構技法、紫色表示我的困擾):
- 建立
CompositeSpec
,以因應未來各種複合式的Spec
。0:00- 和之前重構的技巧一樣,「先用再生」,絕對不要傻傻的手動建立
CompositeSpec
。
- 和之前重構的技巧一樣,「先用再生」,絕對不要傻傻的手動建立
- 將
selectBy(List<Spec>
中部份邏輯抽至specs) CompositeSpec
裡。2:24- 將部份邏輯抽取為
isSatisfiedBy()
( Extract Method)。 - 發現
isSatisfiedBy()
中具有依戀情節(Feature Envy),處理的完全是CompositeSpec
的職責。故將其搬移至CompositeSpec
(Move Instance Method)。
- 將部份邏輯抽取為
- 將
selectBy(List<Spec>
用specs) selectBy(Spec spec)
取代。3:54- 使
selectBy(List<Spec>
透過呼叫specs) selectBy(Spec spec)
完成。此時必須使CompositeSpec
繼承Spec
才能通過編譯。 - 去除
selectBy(List<Spec>
,呼叫端改用specs) selectBy(new CompositeSpec(specs))
。
※ 在這修改過程中(5:49), IDE 會自動變為selectBy(new CompositeSpec(specs))specs)
,必須再手動刪除後頭的specs
,有點困擾啊,不知道有沒有更棒的方式。8:20 也發生了一次。
- 使
- 整理
CompositeSpec
。6:14ComposietSpec
當中的Spec
改為逐一 Add,而非於建構子當中傳入。- 將
getSpecs()
所回傳的List<Spec>
改為ReadOnlyCollection<Spec>
型態。
搞定!
其他 Refacotirng To Patterns 影片請見:Refactoring To Patterns
不堪入目的練功過程:Refactoring To Patterns (exercise)