[Day30] 淺談重構(refactoring)與兩把刷子
鐵人賽的最後一天,讓我們先來簡單的聊聊重構,這部分是筆者之前在看「大規模重構」這本書時整理的內容,目前只看了前幾章,所以能分享的還很有限,但到目前為止我很喜歡作者的觀點和態度。
重構的 what 和 why?
重構(refactoring)指的是「在不改變外部行為的情況下,重組 程式碼的過程」,也就是對於一般的使用者來說,重構前後的差異是不會被感覺出來的,而重構的目的是把原本隱晦、不易理解的程式邏輯、語法、撰寫風格等轉換成對其他開發者更容易上手和友善的程式碼。
先測試、再重構
有些時候或多或少都會有一種想要重構自己或他人程式碼的衝動,但要特別留意的是,在還沒有足夠的測試覆蓋率前,千萬不要貿然重構,因為有不小的機會,會改壞了某個功能而不自知,很多看起來莫名其妙的程式碼,常常有它的涵義在,可能是針對當下的某個 bug 採取的某種 work around,也可能是後來的開發者因為需求變更而隨手加上的邏輯,總之, 當你有一種「蛤,這在寫什麼」的感覺,有一種想要直接把它刪掉的衝動時,就更要小心! 不是不要重構它,而是要更小心謹慎的處理它。
可能的話千萬記得,先測試、再重構。
另外,重構時還有一種情境很常遇到,就是原本只想改重構某個範圍的程式碼,但改者改者卻發現這個功能到處都被使用、有彼此相依的情況,進而導致重構的範圍越來越大,又或是進入了某種重構的心流後,一發不可收拾,甚至開始包山包海。這幾種情況都要特別留意,因為很容易讓 Code Review 的人很難看懂,如果可以,請試著把重構範圍縮限在他人能夠審視的範圍(這句話其實是特別在跟我自己說的,對不起了同事,傷了你們的眼睛 🧎♂️)。
了解當時程式的撰寫脈絡
當你試著要開始重構某段程式碼時,可能的話也可以和當初處理這段程式的人稍微討論看看(git blame 是個好東西),了解當初會這樣寫是否有什麼原因,如此,你就有機會避開前人處理過的地雷,否則別人當時這麼做可能是為了讓你不要踩到這個洞,但你卻挖了個洞給自己跳。
書中這句話是這麼寫的:「每行『壞』程式碼也同樣是要試圖解決某個問題。如果盲目地重構它,你可能招惹原作者小心翼翼避開的臭蟲或陷阱。」
和當初的開發者討論,除了能幫到自己外,也可能幫到對方,也許對方開發時真的沒注意到這樣的寫法有什麼不妥,與對方討論更可以讓對方有再次思考和學習的機會,我想只要態度是開放的,大家都很願意互相學習改進,現在你發現了這個問題與他討論,未來或許自己寫的程式有問題時,對方也會願意和你討論,雙方都能有互相進步和成長的機會。
為你自己開始重構
最後,和測試一樣,當產品時程很趕的時候,通常很難會有額外重構的時間,但還是要多體貼三個月後的自己,如果現在寫的自己就已經看不懂的話,怎麼能期待他人或三個月後的自己看懂呢?有些時候你不需要一段完整的時間來進行重構,可以針對這次發的 Pull Request,自己再看過一次,想想有沒有什麼更好的寫法就很足夠了。
後記:React 前端 工程師的兩把刷子
開始這次鐵人賽後,周圍就常聽到有人撿到新的刷子,不然就是希望我用刷子幫忙刷東西...XD。這次之所以會決定參賽,起初完全是同事 Ken 說服我,說一天只要 300 字,隨便一篇 3000 字的文章就可以拆成好幾天了,想想好像蠻有道理的,過去曾參加過鐵人賽、深知最大的敵人不是系統字數而是自己的我,還是好傻好天真的相信了。話雖這樣說,但 Ken 也是真的每天和我一起趕稿的好隊友。
BTW,他昨天午夜在寫最後一天文章時,突然對我飆罵髒話,我想說怎麼了,難道是睡過頭忘了發嗎?原來是因為他直接在鐵人賽網站用內建的編輯器寫文章時,快寫完的時候不小把視窗關了!所以原本寫的東西都...都...從記憶體揮發了...,懇請大家可以去他最後一天的文章給他一點鼓勵...畢竟他真的寫了兩次(傳送門:Day 30 - Finite State Machine x XState 推薦學習資源)。
一開始我訂的題目其實是「今晚我想來點筆記時間」,目的就是督促自己每天看一點新東西,然後做個紀錄就好,符合一天 300 字的原則,後來某天晚上洗澡時,突然想的,想說不然來整理一下 TypeScript 和測試的內容好了,於是刷子的題目就這樣出來了。
除了同事 Ken 的鼓吹之外,推倒駱駝,讓我馬上決定答應要參加的則是前同事 ycchiuuuu 和 Jen 的詢問 ,他們都是我在前公司就很喜歡的夥伴,所以我很快就答應了。真的好在有參與組隊,特別是在我寫完 TypeScript 的內容後,覺得已經滿足個人目標、有點沒有方向下一個要寫什麼的時候,因為有了不能讓團隊因我而棄賽的壓力,於是就每天一篇又一篇的產出來了。還記得有一天,原本每天都最準時發文的隊友突然還沒發文且失聯,心裡不禁一想,難道我們要斷賽在今天了?然後,我...我終於就可以不要是因為我而鬆一口氣了嗎?
看到今天就知道我隊友最後還是有在當天發文,而且還依然是我們三個裡面最早發的 XD。
最後,感謝有 follow 本文章的讀者,同事 Andy 和 Kyle 雖然老是在底下留幹話,跟我說他原本都只會用 any
...,但還是很謝謝你們的留言,特別是在後期幾乎沒有讀者回覆時,讓我的文章還能保有一點點熱度和回應,也謝謝 TD 告訴我他覺得我的內容對讀者是有幫助的,而且他還說看完後他決定明年要在認真參加一波(咦?),大家明年敬請期待 TD 帶來更精彩的內容!?
總之,今年很開心能再次完賽,終於可以放心的喊出「鐵人賽臻融一」~!。