Introduction
Code smells are neutral, they are not always bad. — Sandi Metz
Last updated
Code smells are neutral, they are not always bad. — Sandi Metz
Last updated
這個系列的起源是在前陣子(2023/08)看了一段由心目中景仰已久的大神Sandi Metz在RailsConf 2016所發表的分享「Get a Whiff of This」。裡面提到了「由氣味到重構」的概念相當打動我。而在簡報中,也分享了一張由Joshua Kerievsky在2005年所建立的對應表格,讓我興起了想要深度研究的興趣,所以有了參加2023 iThome鐵人賽的契機。
Sandi在演講中提到了一個我認為相當重要的概念,有別於過去我們在Clean Code中所時常提及的程式碼中的壞氣味(Bad Smell),她主張氣味實際上是中性的,並不總是那麼糟糕(Bad)。氣味(Smell)提供了資訊,幫助我們判斷與決策。如果你眼前的程式碼永遠不會更改,那麼這些氣味並沒有這麼糟糕,大可選擇放著不改動也無妨。
然而,在多數的情況下,改變與新需求總是接踵而來。在多數的軟體公司或者擁有開發單位的部門,公司是付錢給開發者維護軟體。正是因為內部或外部使用者成天想要改這改那,許願更多更好(?)的功能,程式碼不需要任何改變的情況幾乎不存在。
同時,即使是糟糕的氣味(Bad Smell)也稱不上是一種錯誤(Bugs)。壞氣味依然按照使用者的期望運行,並且符合軟體規格與測試結果。根據定義,重構是修改程式碼的內容,但卻不改變其運行結果。有鑑於此,「重構一個壞氣味」與「修復程式碼中的錯誤」,這兩種行為之間並不能輕易混為一談。畢竟我們期望重構後行為能保持一致,而不是得到不同的結果,即使可能因此可以修復錯誤。當然,許多重構技巧會大力推薦在修復錯誤或是撰寫新功能時也能夠同樣被參考使用。我們會期待能在程式碼撰寫的初始階段就可以考慮到各種避免造成壞氣味的可能,來降低日後需要改動的機會。
因為重構無法帶來結果的改變,換言之無法直接給最終使用者帶來價值(請注意是直接)。有些單位或產業,會習慣性抗拒單純為了氣味去修改程式碼。因為我們每次改動程式碼,總是無可避免地增加風險。
沒有壞就別動他! (If it ain’t broke, don’t fix it.)
有些人堅定的相信,程式碼只有在錯誤或是新需求到來時,才需要且被允許改動。否則的話,單純為了氣味而提交改動程式碼並因此發佈,只不過是一種無謂地增加軟體運作風險的不負責任行為。我可以理解這些考量,在某些產業背景之下或有其依據,但還請原諒我,無法完全打從心底認同這樣子的想法。我自然理解,在有些情境下,軟體穩定度是至高無上的首要原則,例如在銀行業或是任何與錢相關的軟體,特別容易出現這種抗拒改變的文化。甚至為了降低風險,還可能會設置下一些外人所難以理解的奇怪規定,違反最佳軟體實踐的程度足以讓軟體同業大開眼界,如同造訪了 (金融) 異世界。
為了改動程式碼可能增加的風險而緊張不安可以理解,但時常容易被忽略的部分是,經年累月忽視這些氣味而堆積造成的軟體品質腐化,同樣會帶來風險。除非軟體專案帶有明確的效期,例如單次活動網站或是電影中的視覺特效程式,存在很明確結束的使用時間,並且確定不會再次重複使用。否則的話,考慮到軟體的長期品質與可維護性,還有晚上能夠睡得安穩,我堅定相信單純為了氣味而修改程式碼是利大於弊。
為了更好的重構,我們首先需要了解何謂「程式碼氣味」。每種氣味擁有明確的名稱與定義,以及相對應如何去重構他的技巧。在氣味與重構之間存在固定的關係,正如同食譜一樣。當我們想要一份香腸炒飯,我們可以按照食譜準備食材,一步一步按照書上步驟操作。有了這些明文化的建議,每個開發者都可以輕鬆辨識出氣味,並且模仿「食譜上」的重構的技巧,針對程式碼中的氣味進行改善。
在日本文化中,工作職人與工作環境之間的關係是相當被重視的。職人被要求共同擔負起清潔周遭的工作環境的責任,而不僅僅只是依賴清潔人員,以此來展現對工作的尊重,同時也是一種對環境、團隊成員展現感恩的舉動。我認為軟體開發者需要維護的環境除了物理上實體的辦公環境以外,專案內的「開發環境」當然也是我們專業上需要顧及「整理、整頓、整潔、整齊」原則的地方。
甚至我認為,整潔的程式碼(Clean Code)比起桌面與環境的整潔,對於我們開發者來說更加重要。桌面一時髒亂或許有時還能睜隻眼閉隻眼,但是程式碼髒亂就是不行!這是我們身為開發者應有的專業矜持。
我無法確定這樣依照氣味去改善優化的步驟會有多快能夠被AI助理取代,但是即使是與AI協作,開發者依然必須具備有殷實的知識,否則開發者將無法在AI有禮貌且周延的胡說八道時指正出來,來展現我們把關的專業。
接下來我會粗略介紹程式碼氣味的五大類,各種氣味的細節與重構技法將在接續的日子中陸續提及:
比需要的還大,太多太大。
錯誤使用物件導向的概念。
Repeated Conditional Complexity (Switch Statements)
會讓你很難修改的氣味。
物件通通黏在一起成龐然大物,很難單獨進行修改。
早該拿掉刪除的部分。
與多數的理論相同,不同人有不同的分類看法。這裡主要參考Sandi的觀點進行修正。
Get a Whiff of This, Sandi Metz https://youtu.be/PJjHfa5yxlU
Refactoring Guru https://refactoring.guru/refactoring/catalog