軟體開發的策略層級工作
許多從事軟體開發的人都有過這樣子的經驗:「程式碼因為有一些重複或是不良設計,當需要做變更時,一句話就可以講完的改動,卻必須改動很多不同的地方,也因此變得複雜又容易做錯。」上述的現象可以稱為「變更放大」,那我們有辦法做到「變更縮小」嗎?
在某公司,一群企業高層聚在一起,召開會議討論重大的組織方向調整。開會前,大家都了解本日應該要討論的是策略。當真正開始開會時,進行到了某個關鍵點,當有人開始提出一些執行的困難之後就一發不可收拾,與會者都紛紛開始紛紛進入細節做討論。最後,會議嚴重超時,而組織依然沒有討論出新的策略方向。
類似的故事聽起來耳熟嗎?明明是高層,卻不討論策略、專門探討細節。我的許多軟體工程師朋友,談論不適任的管理階層時,做出的結論也常有相似之處:「善長做下屬的工作,卻不善長自己的工作」或是「戰術一流、策略三流」。
不幸的事情是,軟體開發人員也常常被捲入無窮底層細節 (戰術層次),因而難以抽神去思考真正關鍵的商業領域問題、使用者需求、與規格制定問題 (策略層次)。
技術決策導致的無窮細節
有些團隊選擇技術時,喜歡選用流行的技術,比方說,最近流行 NoSQL,好吧,那就用 MongoDB 或是 Cassandra 吧?接著照著網路上的最佳實踐 (best practice) 來開發系統。做了一陣子之後,咦,好像有點怪怪的,為什麼本來用 SQL 三兩下就可以做出來的事,改成很潮的 NoSQL 之後,卻要花費三倍到十倍的力氣才能做出來?
常常發生的情況是:終於團隊的成員覺得好像不對了,該重新檢討了,這時候才醒悟:「以公司軟體所需要承載的流量,實在不需要選擇超高效能的軟體架構。」換言之,這是一種過早的最佳化 (premature optimization) 。
同樣的故事卻會引出不同的論點,有一派的主張是:『應該選用無聊的技術 (boring technology)』原因是,無聊的技術由於已經被時間驗証過、被大量的人使用過,風險低得多。就算遇上了奇怪的問題,網路上也很容易找到答案。
迴避風險 vs 變更縮小
我不太同意「選擇無聊的技術」做為主要的技術選型指導原則,原因是:要快速抵達終點,除了控制風險之外,更重要的應該是前進的速度要快。選擇無聊的技術比較像是迴避風險,而想要追求前進的速度,應該要選擇可以讓變更縮小、讓開發人員得以在策略層級工作的選項。
有三種常見的作法,對於變更縮小會有正面影響,以下依照實施的難度排序:
避免「過早的最佳化」
選擇函數式程式語言 (functional programming language)
將 policy 與 mechanism 的程式碼分開
第一種作法,有一定經驗的軟體開發者通常可以做到,但是,嚴格地來說,這個作法比較算是避免變更放大。
第二種作法目前只有少數的軟體開發人員了解,實施的最大難點在於說服管理階層採用。有成功實施的話,軟體專案的品質會有明顯的變更縮小效果。然而,根據 RedMonk 的程式語言排名,Scala, Clojure 等函數式程式語言沒有進到前十名過。
第三種作法最進階,極少數的軟體開發者有徹底掌握這個技巧,在他們之中的許多人,會被稱為 distinguished engineer。第三種作法表面上不受限於程式語言,但實務上,卻比第二種作法更難實施,因為 distinguished engineer 幾乎是可遇不可求。
總結
業界很喜歡談論「敏捷開發」、管理階層也常常覺得軟體部門的生產力不夠,因而招募更多的軟體開發人員。那開發速度不夠快的根本原因是什麼?公司的軟體開發人員有花費足夠的時間在策略層級工作嗎?還是多數工作時間都一直都沉浸在底層的細節裡?


