什麼是重構(Refactoring)
在開始講重構前,先來講個小故事:
臺中都會區鐵路高架捷運化計畫目前豐原到大慶的高架化工程已完成九成左右了。以下撇開政治因素與技術細節,純粹就維基資料來討論鐵路的規劃。
鐵路的功用,正是讓電車能在上面跑。但電車不管在平面鐵路或是高架鐵路都能跑,為何還要多此一舉把平面變成高架?主要有三個原因:平面鐵路穿越台中,會造成前後站發展不均;鐵路與道路交錯點需要平交道,尖鋒時間容易造成交通壅塞;除此之外,另有預算增設五個區間通勤車站。
奇怪?既然會有這些問題或需求,又為何不一開始直接衝高架蓋好蓋滿?這有幾種可能:
- 當初蓋平面鐵路的時候,還不具備蓋高架鐵路的技術。
- 當初蓋平面鐵路的時候,自用車不多,不容易發生交通壅塞的問題。
- 當初蓋平面鐵路的時候,沒有像現在一樣大量的通勤需求,所以不需要那麼多通勤車站。
以上是合理推測,但畢竟不是鐵路系,真實情況歡迎留言回應
因此,當初規劃平面鐵路並沒有問題,而隨著時間推演與環境變化,平面鐵路漸漸不符合需求,才會需要進行鐵路高架化。
重構一詞,如同 DevOps 或 Agile,大家對它的認知都有點不大一樣,有的人認為是砍掉重練、也有人說是效能優化。
一位知名的軟體工程大師--Martin Fowler,它寫了一本書:Refactoring - Improving the Design of Existing Code(中譯「重構:改善即有程式的設計」)
在這本書裡,Martin 是這樣定義重構的:
Refactoring is the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure.
中譯版的翻譯如下:
在不改變程式碼外在行為的前提下,對程式碼做出修改,以改進程式的內部結構。
重構就很像鐵路高架化一樣,它並不會改動原有功能(外在行為),而是改進設計。程式原本跑好好的,哪會有人閒閒沒事去動它。但遇到業務需求需要修改程式,也只能跳下去修改,而且還不準改壞。
有維護經驗的軟體工程師都知道,遇到好改的程式碼是要看人品的,除了前人設計好之外,業務需求也剛好落在預期更動範圍內,程式碼才會好改。人品不好,就有機會看到設計不良、難以修改的程式碼,加上跟原本設計不搭的業務需求。
上述兩種狀況都很極端,以一個常態分佈的狀況下,通常會遇到一個設計還算可以的程式,但開始難以應付新需求。可能程式是自己一手維護,但同時也隱約感覺到它出現了瓶頸。
為什麼需要重構?
由前面的故事可以了解,現實生活中我們最常遇到的是:現有設計無法輕易的滿足業務需求,這時有幾種選擇:
第一、解決不了需求,那只好解決提出需求的人。但通常有很高的機率被提出需求的人(如老闆)解決掉。
第二、在現有設計下,硬是把跟設計不合的功能實作出來。這個方法又稱為 workaround,因省下重新設計的時間,通常都能以較短的時間完成需求,但這些省下的時間都會在未來付出代價。
第三、山不轉,路轉!那我們把程式改成「可以輕易滿足需求的設計」就好了呀!這方法跟 workaround 剛好相反,當下花時間設計,但會省下未來修改的時間。是的,這就是本次鐵人賽的主題--重構!
講了這麼多,為何我們需要重構?甚至還有專門的書在說明重構的技巧?
環境會變,需求也會跟著變,沒有人能保證鐵路不會變高架,也無法保證自己的程式碼不需要修改。重構技巧可以補足設計,也能提高程式碼品質,讓程式碼更好維護,並更能應付需求變化,這就是為何我們會需要重構!
今日回顧
- 計畫趕不上變化,架構規劃趕不上需求一句話。
- 設計再怎麼好,都無法應付需求變化;而重構能改善設計,提高可維護性,因此我們需要重構。