心得-Refactor Tennis Game By Baby Step in Java

在實務上常常遇到的情況是針對遺留程式碼做調整,這些 Code,有一些是半年之前的我自己寫的,有一些是別人寫的,不可避免的是我無法記得所有系統的細節,所以很多時候我必須要先重新看過一次程式碼,知道在做什麼事情之後,才能開始修改,如何修改Legacy code都是老生常談了,這次有機會可以從頭到尾感受一下Joey的重構影片,尤其是都有旁白說明,是非常難得的機會,推薦給大家看看

Joey針對這個主題也錄製了影片、撰寫了文章、提供了完整的 Github Commit History,相信可以讓大家更完整的感受到重構的威力、及善用工具的優勢

影片連結:[Fake it till you make it] refactoring tennis by baby steps in Java - By Joey Youtube Channel
文章連結:重構全 hard-code 的 tennis

還不了解 Tennis Game的人,可以先看一下Tennis Kata的規則說明,其實就是網球的計分規則,在網路上關於Tennis TDD Kata有不少文章,大家可以自行搜尋一下。

Magic String / Magic Number

影片中第一件事情就是去除掉Magic String,又或者是數字,那就叫做Magic Number

這些東西不注意的話就會充斥在整份程式碼當中,事過境遷,真正的意義很可能被遺忘在歷史長河中,為了避免這件事情,應該要用一個有意義的變數取代這些寫死的字串(或是數字)。

抽象共用的變數

這是影片中第二個用到的技巧,實務上這樣做的原因也很簡單,你不會想要同時修改很多次,如果你只需要修改一個地方,那不是很好嗎?所以將所有相同的字串都用一樣的變數取代掉,這個技巧在影片當中的速度很快,快捷鍵看樣子是按下Ctrl+Alt+F,這在 Intellij 裡面應該是把東西變成Field的快捷鍵,但是我在Rider裡面並沒有辦法像影片中那樣,只抽取反白的區域而已,如果有相同的字串,在Rider裡面也會問你是否要處理所有相同的字串,這點很方便

讓分數與顯示結果的關係更明顯

為了讓玩家的分數,與實際顯示的字串對應關係更明顯一點,透過HashMap來存放這份關係,讓使用者分數為 Key,這樣的方式會更清楚,相對的也可以將原先的邏輯,逐漸替換掉,讓分數作為條件,取得對應的文字顯示,在 CSharp 裡面,我常用的也是Dictionary,在Javascript則可以直接用{}的方式來宣告,這些都是 Key-Value-Pair

整理程式碼區塊內的程式

對應關係的HashMap是固定的,其實可以在Create Instance的時候就建立好,這樣子實際上取得分數的方法內,就只需要包含邏輯就好,不再有初始化的事情,讓職責更清晰,也讓三個月後的你回來看 Code 能更快速的理解程式碼邏輯

Inline 變數

在影片後面接著會將所有的變數搬來搬去,到最後放到 HashMap 的時候,最後一個動作是把變數 inline 進去,一開始抽象出來是為了 reuse,最後 inline 是為了消滅非必要的變數,這一系列的過程其實就是重構,重構最常做的事情其實也就是這樣子,改一下命名,把東西搬過去、搬過來、抽出一個 Function 之類的,最終的目的都是為了讓程式碼更容易理解

合併相似的邏輯

程式碼中有很多 if 分支,在裡面的邏輯是都相同的,所以這個時候可以將判斷修改一下,就可以移除重複的程式碼

組織程式碼順序

這個行為我不太知道該怎麼說,影片中是將類似的邏輯放在一起,這也有助於理解程式碼,透過這樣的搬移,又發現這幾個程式碼都有相同的邏輯實作,所以又可以精簡,這樣的動作不一定每次都奏效,但起碼可以幫助你理解程式碼的行為,類似的行為放在一起總是更容易理解不是嗎?

影片中的範例透過這樣子操作,合併判斷式之後最後又發現可以進行更精簡的修改,逐漸減少判斷條件,程式碼也越來越清晰,如果有練習過 Tennis TDD Kata 的人,應該到這邊就開始發現,程式碼開始有點像了

取個容易理解的名字

具體的範例就是影片中的isDeuce()sameScore()lookupScore()這樣的東西,一看到這個 Function 名稱,你就知道它在幹什麼的,它怎麼實作的,你不要去管它,讓你的注意力集中在商業邏輯,而不是實作方式,當然方法的內容也要清晰明瞭

重複這些操作

在部分合併後的判斷式調整,需要用腦子去想想商業邏輯,應該怎麼改寫可以更簡單,其他都是重複操作了,最終你看到的程式碼,所有方法都是一行,而主要的方法邏輯很清楚,你可以透過方法的名稱知道整個商業邏輯,計算分數的規則是甚麼

心得

我寫完程式碼之後,也都是用上面的方式來 review 我的程式碼,在剛入這行的時候都不知道這些事情,所以跌跌撞撞了很久,這些東西跟技巧都很簡單,但是觀念的培養是需要時間的,要不然就是真的踩雷才會記得,推薦這影片給大家,有機會多看看,重複看也很不錯,這影片暴露的東西很多了

  1. 如何善用你的開發工具:熱鍵、Vim、IDE 重構支援
  2. 如何理解你的需求:透過Joey的旁白,你可以知道判斷式修改是為什麼,如何組織在一起的,為什麼可以這樣合併,這些都是需要先理解需求,才能知道應該怎麼寫的

這也是我推薦給大家的主因,理解需求,並修改既有的程式碼