最近在客戶那邊一起 pair 重構 legacy code,
碰到了一大段 if/else statement,用來判斷什麼時候該使用哪一種cache,
並依照不同 cache 的邏輯來決定回傳的內容。
發現還是有蠻多風氣比較封閉的公司對這類型的基本功跟處理不是很熟悉,
可能是對 code smell 不熟,對重構不熟,對 design pattern 不熟,對工具不熟。
因此,我用自己幾年前的一個「計算運費」的範例,設計成這類型程式碼重構的簡介。
這個範例之前是 C#,這次示範我改用 Java,用 IntelliJ 來重構。
有整個重構過程的 IDE 操作影片,也有每一個重構 baby steps 的 commit history。
影片:https://youtu.be/zO-NnNC-xyg
GitHub commit history: https://bit.ly/strategy-91
也可以參考 《Refactoring to Patterns》 的
Replace Conditional Logic with Strategy:
https://www.informit.com/articles/article.aspx?p=1398607&seqNum=2
IntelliJ/Android Studio 在重構上還是地表上最強的兵器啊。
推,legacy code看到if又case又if真的吐血
shipper輸入的部分還有改善的空間嗎?感覺用字串很容易出包...
作者:
alihue (wanda wanda)
2020-12-14 09:16:00包成 enum 吧,然後在 convert 到 enum 時做 err handling
作者: kkjkj (kk) 2020-12-14 11:49:00
樓上,我想問一下當如果enum沒該對應,怎麼處理比較好?
作者:
alihue (wanda wanda)
2020-12-14 12:28:00Throw exception.
作者: superpandal 2020-12-14 12:47:00
噗 XDDD
作者:
tbpfs (http://0rz.tw/Uk989)
2020-12-14 14:36:00改用kotlin重構,你會看到新世界
作者: kkjkj (kk) 2020-12-14 15:17:00
這樣switch的default動作用exception有點不太妥吧?我會這樣問是我曾經是在對應後,外面增加判斷是否null想知道有沒有其他方式,處理對應不到的情況
重點應該是對應不到後的行為,如果這本身就是不合法的操作,你在外面檢查到 null 之後,還是要丟 exception 啊。
作者:
alihue (wanda wanda)
2020-12-14 15:38:00還是看當下商業邏輯,如果走不下去直接丟 ex 外面就不用檢查 null 更乾淨
作者: kkjkj (kk) 2020-12-14 15:39:00
switch的defalut動作是合法的阿<=這邊在於討論改成enum情況
作者: aoma 2020-12-14 15:39:00
推~
作者:
alihue (wanda wanda)
2020-12-14 15:42:00你應該不會想要全部用到的地方都檢查 null,把責任丟給convertor ,錯就丟 ex,如此一來其他地方直接用 enum 就乾淨很多
作者: kkjkj (kk) 2020-12-14 15:43:00
我知道你的使用情況了,我的情況是要吐不同的ex才多判斷null
作者:
alihue (wanda wanda)
2020-12-14 15:45:00對 還是根據你的情節決定 default 幹什麼事,說不定你們有default enum
作者: dog30111 (安) 2020-12-14 15:54:00
怕null做個空物件
作者:
undersky (undersky)
2020-12-14 16:33:00推~ 影片看不是很明白但git history很清楚
謝謝樓上幾位的鼓勵,我培訓中的練習題都是這樣呈現的
enum class Shipper implement Product interface override caculateFee method.另外 Shipper constuctor宣告 shipperName 屬性 強迫每個 enum 一定有 name屬性 再把 Cart 的 hashmap 替換成 Shipper.shippingFee(input) static method 裡面用 values() 比對 name找出對應的 enum 再呼叫 caculateFee 即可這樣就沒有 if 也沒有 map 也沒有 Cart class
你這個應該不能叫做策略模式,因為沒有動態 injection另外我滿好奇你覺得的 code smell 是指什麼在我看來你的 refactor 只有把 if 取代成 map除此以外結構上並沒有什麼太大的差異
data clump 變成 parameter object: Product順帶一提,歡迎大家把自己的想法、重構、設計呈現出來soure code 在 github 上,連 branch 都開好了歡迎fork回去,自己錄一版重構的影片跟repo放上來討論soure -> source
if 的確很難維護啊,光是改成switch 就有部分防呆效果了。