人們對「品味」的概念各有見解,談到程式碼是否有品味,開發者又是如何執行判斷?Linux之父 Linus Torvalds曾提到一個案例來說明,他認為,重點並不在於邊界情況(Edge case),而是能以不同的角度看問題、直覺地選擇出正確的方法。

Linus的品味案例

在2016年舉行的一場TED訪談〈The mind behind Linux〉,Linus說明了Linux的創建、對開放原始碼的想法、Git的發想,以及程式碼是否具有好的品味(good taste)等內容,在這次公開訪談中,Linus展現其率真的一面,也坦誠自己不擅社交,很多目前看來偉大的專案,其實一開始都只是以自己為出發點,想要能好好地獨立工作而開始的。

整個訪談內容滿對我的胃口,畢竟我也不是那麼愛社交的人,如果你也是個以自身為出發點在做事的開發者,應該也能從中獲得不少共鳴;在訪談中,有一個稍微技術性的區段是,主持人問到了Linus具有的特點之一,也就是對於「品味」的想法(14:10),為了具體地示範品味,Linus秀了一張不算是有好品味的程式碼,以及另一段有較好品味的程式碼。

這兩張擷圖的內容,都是從單向鏈結串列移除指定項目的實現,有趣的部份是後者少了if/else,而這個if/else本來是要判斷想移除的項目是否就在鏈結開頭,希望顯著區隔出兩種不同的情況,而開發者第一次試著寫個鏈結串列,多半也是從這個教科書式的範本實現開始的。

而且,Linus的第二張擷圖使用了指標,直接用指定項目的下個項目,將指定項目覆蓋,就該實現來看,整個過程只有一種情況,從而不必使用if/else來判斷項目是否就在鏈結開頭;自此之後,有些文件談到程式碼的品味時,會稱這種對邊界條件(edge case)的消除,是對於品味的一個基本要求。

不過,在Linus的訪談中,他並完全沒有談到邊界條件的相關字眼,最多就只是提到:有趣的部分是if的那個情況。他後續也補充,表示這個例子甚至跟品味不太相關,因為太小了,實際上,好的品味跟大的模式有關,那是一種直覺上知道正確處理事物的方式。

程式碼有品味?

那麼「品味」是什麼?具體一點來說,談到一個人對於酒有品味時,單單只是他對味道的感受嗎?

不是吧!味道是很主觀的感覺,談及對酒的品味,往往涉及人們對酒的認識,像是品牌、產地、原料、歷史、釀造方式、製作者等,又或者是對於相關事物的文化認識,像是使用的杯子、相佐的食物、侍酒師、禮儀應對等。

因此,人們對品味的見解不同,往往就在於各自具有的知識、文化等深度的不同,從而影響了判斷何謂「美」、「好」和「對」的能力。

事實上,Linus的第一張擷圖本身沒有錯,正如他談到的,任何學過鏈結串列開發者都知道要這麼寫,然而,第二張圖結合了語言的特性,而懂得C語言的開發者只要兩相比較,自然而然地都會對後者發出「對喔!這麼做更漂亮!」之類的感想,從而顯得前者的實現上膚淺許多。

也就是說,程式碼的品味在於,展現出開發者對使用語言的認識,是否在對的場合使用了對的元素,這類元素有時是語法,有時是慣例,有時是語言的特性、更大的模式,或像是社群文化之類的概念。因此,當我們面對問題時,如果選擇了什麼,往往牽涉到許多細節,而對於具有這類深厚知識的開發者而言,能夠整合這些元素,從中找出適當而正確的處理方法。

若要具體一些,我們可以舉出多個例子。像是在Java中,適當地使用Stream API;而在Python中面對錯誤時,我們知道該選擇採用LBYL風格,或是EAFP風格(參考先前專欄〈把例外當成例外〉);到了JavaScript中,可以善用一級函式、非同步、物件實字等,而這些做法都是展現程式碼品味的一種表現。

一般而言,學過多門語言的開發者,有不少會落入「語言不重要」的想法,確實地,各語言能解決的問題集是有重疊的部份,A語言解決問題的方式,依樣畫葫蘆地用B語言實現,也是有可能的,只不過從程式碼品味的角度來看,這樣的程式碼一定沒有品味,就像個粗製濫造的成品。

是的,或許它可以運作,也可以解決問題,只不過,如果是個有品味的開發者,一定無法忍受這樣的程式碼。當然,有人會說:「公司花錢是請你來解決問題的,不是展開品味的」,只不過經營管理是另一番話,這邊純粹是在談程式碼的品味,另一方面來看,這也是種二分法的謬誤,為什麼面對品味與解決問題時,我們只能二擇一呢?

不同的角度看問題

事實上,關於品味與解決問題,並不是個二選一的難題。Linus在訪談中也說過,他希望大家瞭解的是:有時候,你可以用不同的角度看問題,而對於語法、慣例、語言特性、模式、社群文化等,如果可以認識得越多,當下能選擇的角度也就越多。粗製濫造的程式碼固然是可以解決問題,然而,這可能也代表了一件事:手邊可以解決問題的方式,少得可憐。

好吧!來個經典的戰文標題:「寫程式需不需要用到數學?」的確,許多領域可以不用到數學,而且,也可以透過寫程式來解決問題,這也是一部份開發者(引以為傲)的想法,他們認為,重要的是邏輯能力。事實上,邏輯當然是解決問題的一種方式,只不過面對一些問題,數學可以讓你用其他的角度來看待同一個問題,你也能處理更多需要數學才能解決的問題。

據說過去有個老師,給小朋友們出了道題目「1+2+3+...+100是多少」,許多小朋友開始埋頭從1開始逐一加上數字,然而有個叫高斯的小朋友,一下子就算出結果是5050。

許多初學程式的新手,面對「1+2+3+...+100是多少」,可能會想到使用迴圈吧!就像高斯的同學那樣;然而,如果是對數學稍微敏感的人,應該會意會到這是個等差級數,套個公式就解決問題了,據說當年的小高斯是觀察出來的,因為他發現這些數,頭尾兩兩相加的結果都是相同的,也就是有50個101,很快就能算出結果是5050。

有人會說,那些高深數學都有人包好程式庫,我拿到之後、兜一兜就可以啦!的確,這也沒錯,只不過,有能力包程式庫的人為什麼不是你呢?哪天如果想用的東西,卻沒人包好程式庫,屆時又該怎麼辦呢?

直覺地選擇出正確的方法

Linus說到程式碼的品味,往往展現在面對問題時,能否以不同的角度看待,而他之所以舉出第一張圖,我想,他只是想表示:「喔!標準而教條式的處理方式,像個小學徒似的,只會用這種方式解決問題!」。

對於Linus想與其共同工作的人,他也說,這些人都有個現象,就是有好的品味。他談到,這些人好像有直覺,可以選擇出正確的方法,當然能找到對的方式,絕不是憑空得來,應該是表示,他想跟一群「有料」的人合作,也就是,與看待事情不會只有一種解決方法的人做事吧!

專欄作者

熱門新聞

Advertisement