引言
Any fool can write code that a computer can understand. Good Programmers write code that humans can understand.
— M. Fowler (1999)
任何一個傻瓜都能寫出電腦可以理解的程式,唯有優秀的程式設計師能寫出讓人讀懂的程式。
上述引言是個人在讀完本書後蠻喜歡的一句話。初學程式時認為寫程式是在跟機器溝通,它懂了、可以動了,我的目的達成了,結案!然而大多時候,光是連編譯器吐出來的錯誤訊息都看不懂,更別說是考慮自己寫出來的程式碼的可讀性,而且專案太小也感覺不出維護上的困難。
工作後見識到老舊專案的核心程式,疊床架屋的結果下加新功能,每一步都得小心翼翼。理解既有程式碼要花時間,更改程式碼也是一項大工程,尤其是在多人協作開發的環境下,程式碼的品質更顯重要。
接續之前的clean code演講,偶然在書店看到了演講中提到的《重構》第二版。作者為了讓更多人容易吸收書中想表達的意涵,第二版範例改用javascript呈現。老實說讀技術相關的工具書,中文翻譯常常會混淆一些名詞所表達的意思。不過比照大學啃原文書的方式,看懂了範例就成功了一大半,順便培養作為工程師必備的基本能力--推敲上下文(通靈)。
定義何謂重構
重構指在不改變程式原有行為的基礎上,對既有程式碼進行修改,以改進其內部結構。
簡單從定義上,站在管理者的角度來說,佔用了時間卻沒有任何產出!況且高機率會遇到以下情況:
- 原本正常運作,為什麼要改?
- 都是你把它改壞的!
- 第1種狀況:最好的情形下,要有能說服長官的依據,只是過多不可控因素考量,不如不要讓長官知道你在重構!
- 第2種狀況:必須要確保能夠安全的重構,具體的方式即:先撰寫測試。
撰寫測試
這裡帶到了測試驅動開發的概念(Test-Driven Development, TDD),在完成產品的程式碼前,應該要建立對應的測試程式碼,並且每一次的改動都要能通過原有的測試案例。一方面,這些測試案例也透露出開發程式碼應達到哪些基本的功能要求,讓需求意圖跟著被保留下來。另一方面,在重構的過程中,開發人員也會間接被要求寫出更容易被測試的程式碼,讓程式單元趨向單一職責(Single-responsibility principle, SRP )。
善用整合開發環境(IDE)
Java常用的IDE(IntelliJ, Eclipse)或是微軟Visual Studio內插件支援resharper,都可以幫助開發者進行重構,包含擷取方法、擷取類別、變數內嵌或是重新命名。
以我自己遇到的專案為例,從前輩手中接手上千行的批次程式,在沒有撰寫測試程式碼的狀況下,只能不斷擷取出方法,並且個別給予能描述其方法的命名,順便梳理整個大區段程式碼的邏輯。如此一來,就算執行後還是出現問題,也能快出推斷出是哪一個單元發生狀況,最後順利在上線前,額外多解決了幾個bug。
// 修改前示意
function main() {
...
...
...
}
// 修改後示意
function main() {
doOneThing();
doAnother();
doTheOther();
}
function doOneThing() {
...
}
function doAnother() {
...
}
function doTheOther() {
...
}
結尾
The whole purpose of refactoring is to make us program faster,
producing more value with less effort.
書中後面章節大多是重構時所使用的手法,因此了解前面幾個章節作者所要表達的概念及範例後,在開發上也會有更新一層的認知。
整體而言,更適切的達到實質的clean code。