面試官的考量一文,談到了統計性歧視與品味性歧視,這篇想來談談品味。
在我學藝不精的時候,常常做一些轉換複雜而非分解複雜的事。比方說,後端程式需要處理『時間』,過去的我沒有去認真思考,Java Joda-Time 明確區分數種不同的時間型別的使用方式:『Instant, DateTime, LocalDate, LocalTime, LocalDateTime』等等,就隨便用了一種,只因為這樣子開發起來比較省事。等到軟體上線執行之後,即使因為軟體被布署在不同的時區執行而造成了錯誤之後,我還是死不認錯,沒有回去改寫程式,反而硬是直接把 server 的時區改掉…,讓程式可以動。
昔日的作法,面對『時間』的複雜時,我不是好好地去分解複雜,反而是轉換複雜,把複雜從開發端 (development),移轉到布署端 (deployment)。類似的錯犯過了數遍之後,總算產生了一些品味:
處理複雜如果用轉換的,通常還是會轉回到自己身上。
該花時間研究的文件、資料、理論,如果偷懶不研究,往往之後會要一邊解 bug 一邊研究。
函式庫的品味
軟體開發需要串接不同 API 、又或是處理特定的資料格式,通常會利用函式庫 (library) 來處理。過去缺乏品味的時候,選擇函式庫的考量是:
是否還有人在用?
github 有幾顆星?
函式庫的文件與範例,是否容易看懂?
上述的三項決策考量不算完全不合理,只是難以迴避風險、也不容易選到高品質的函式庫。
首先,是否還有人在用,這點其實我無法確切得知。有一些函式庫很穩定,很少出問題,品質良好,這樣子一來,它在 stackoverflow 上被問的問題,反而會相當少。github 有幾顆星這個作法特別容易向『平庸』回歸,因為平均值通常就是平庸的結果。函式庫如果是高手寫的,有時候這些高手因為知識詛咒的關系,寫得微言大義,一般人反而看起來覺得很吃力。只因為嫌看起來吃力就不選,就很容易錯過高品質的函式庫。
後來,我加了一條新的決策考量:
看一下函式庫的實作,看有沒有無意義的複雜:「只是提供一些很小的功能,不是自行實作,卻引用了一堆其它函式庫的函數來做出。」如果有的話,最好不要選,因為這種函式庫通常是水準差的人開發的。
模組化的品味
開發軟體時,總是會不停地遇到需要開發的新功能,恰好就是把一大段程式碼複製、貼上、改一部分的情況。這種情況,教科書上說,最好要把共同的部分模組化,否則將來的變更放大會讓人很吃力。
然而,我跌倒了很多次才學到的品味是,先乖乖地「複製、貼上、改一部分」,不要急著模組化。程式沒有寫到一定的程度之前,我們往往不知道,日後功能會往哪一個方向發展,過早進行模組化,如果提練出來做為模組的共同部分不夠精準,最後這些模組反而會浪費時間。原因是,共同部分被模組覆蓋太少的話,一樣會有變更放大的問題;共同部分被模組覆蓋太多的話,則模組很多情況下會無法套用。
所以我後來鐵了心遵照前人的建議:
重複的部分沒有出現3次以上之前,先不要急著模組化。
創新的品味
我也曾經跟很多人一樣,喜歡一窩蜂驅動開發,一直想試試看新的技術。倒不全然是為了要洗履歷,更多的反而是一種幻想,「會不會我成功嘗試了這個之後,日後開發就超快,從此就過著幸福快樂的日子。」
大部分基於一窩蜂驅動開發的嘗試都失敗了,除了 Clojure 之外。
創新的重點不是在『新』,而是在『提高產出』。而可以有效提高產出的作法,往往需要對問題本身有全新的觀點或是認識。換言之,與其不停地嘗試新解法,不如重新認真思考,問題的本質是什麼,有沒有可能用新的觀點來看問題?
近幾年來,有一本書 idea flow 提了一個新觀點來思考軟體開發:概念流溝通模型,即,把軟體開發這件事,看成是人類在跟電腦溝通,這個溝通的過程可以看成兩種迴圈。
一致迴圈
衝突迴圈
如果我們想要流暢地前進,那自然是必須待在一致迴圈裡,而且學習方塊佔用的時間要短。如果我們是一直處於衝突迴圈裡,那想必是有許多需要改進的地方,比方說,因為缺乏品味,所以只好一邊解 bug 一邊研究。
結論
有看過別人說過
要找軟體工程師,最重要的是要看品味。
有沒有誰的品味跟我類似的?