在特定條件下,「軟體變更成本隨時間指數上升」這條曲線是可以被壓平的。而一旦曲線被壓平,關於「軟體該怎麼開發最好」的舊假設就不再成立。

那條被當成定律的曲線#

軟體工程有一條普世假設:修改程式的成本隨時間指數上升。

作者還記得大三時坐在鋪著油氈地板的大教室裡,看教授在黑板上畫出那條曲線,並說:

修正軟體問題的成本隨時間指數上升。一個在需求分析階段發現、只要一美元就能修好的問題,等軟體上線後可能要花上數千美元才修得掉。

圖 1:變更成本隨時間指數上升

當下作者就下定決心:絕不讓任何問題流到正式環境。他要盡早抓出問題、事先解決所有可能的問題、審查並交叉檢查自己的程式碼——絕不讓雇主付出十萬美元的代價。

延伸案例:三十分鐘改掉一個核心資料結構

以下是作者最近在一套壽險合約管理系統上的親身經歷:

  • 17:00——我發現,就我所能判斷,系統裡那個「一筆交易可以從多個帳戶扣款、貸記到多個帳戶」的華麗功能根本沒被用過。每筆交易都是從一個帳戶來、到另一個帳戶去。有沒有可能把系統簡化?

圖 2:借方與貸方能否各自只用一個元件?

  • 17:02——我請 Massimo 過來一起看。我們寫了一個查詢:系統裡的 30 萬筆交易,每一筆都只有單一借方與單一貸方帳戶。
  • 17:05——如果要修正這個錯誤,我們會怎麼做?改掉 Transaction 的介面,再改實作。我們寫了必要的四個方法,開始跑測試。
  • 17:15——測試(一千多個單元測試與功能測試)仍然 100% 通過。我們想不出這些改動會失敗的理由,於是開始寫資料庫遷移程式。
  • 17:20——夜間批次跑完、資料庫已備份。我們安裝新版程式碼,執行遷移。
  • 17:30——跑了幾個健全性測試。所有我們想得到的都正常。想不出還能做什麼,就回家了。
  • 隔天——錯誤日誌乾淨,使用者沒有抱怨。變更成功。

接下來幾週,新結構還催生出一連串進一步的簡化,讓他們得以為系統的會計部分開放全新的功能——而且過程中系統變得更簡單、更清晰、更少冗餘

如果那些投資真的有回報呢#

近數十年來,軟體開發社群投入了龐大資源想降低變更成本——更好的語言、更好的資料庫技術、更好的程式設計實踐、更好的環境與工具、新的標記法。

如果這些投資真的奏效了呢? 如果變更成本不是隨時間指數上升,而是上升得慢得多、最終逼近一條漸近線呢?如果明天的軟體工程教授在黑板上畫的是另一條曲線呢?

圖 3:變更成本可能不會隨時間劇烈上升

這正是 XP 的前提之一——XP 的技術前提

如果變更成本隨時間緩慢上升,你的行為會和「成本指數上升」假設下完全不同

  • 你會把重大決策盡可能推遲到流程的後段,以延後決策成本,並讓決策正確的機率最大化
  • 你只會實作當下非做不可的東西,並期望你替明天預想的需求不會成真
  • 你只在「能簡化既有程式碼」或「讓下一段程式更好寫」時,才把設計元素引入系統

反過來說:平坦的變更成本曲線讓 XP 成為可能,陡峭的曲線則讓 XP 不可能。 如果變更代價高到毀滅性,那不經審慎前瞻就往前衝就是瘋了。但只要變更維持便宜,早期具體回饋帶來的額外價值與風險下降,就會勝過早期變更的額外成本。

曲線不會自己變平#

把變更成本壓低不會魔法般自動發生。有些技術與實踐能讓軟體保持柔軟。

技術面

  • 物件(objects)是關鍵技術。 訊息傳送(message sending)是一種便宜地大量製造「變更機會」的強大方式:每個訊息都成為未來潛在的修改點,而該修改可以在不觸碰既有程式碼的前提下發生。
  • 物件資料庫把這種彈性帶進永久儲存的領域。由於程式碼是附著在資料上,而非像早期資料庫技術那樣分離,物件可以輕鬆從一種格式遷移到另一種格式。即使找不到遷移辦法,也可以讓兩種替代實作並存。

這不是說「非有物件不可才有彈性」。作者說他學到 XP 的根本原理,是看著父親用組合語言寫即時製程控制程式——父親發展出一種風格,讓他能持續精煉程式的設計。不過依作者的經驗,沒有物件時,變更成本曲線會陡得多

這也不是說「有物件就夠了」。作者見過(老實說大概也寫過)一堆沒人想碰的物件導向程式碼。

實踐面——從前述案例中,可以歸納出讓那套程式碼在上線多年後仍容易修改的三個因素:

  • 簡單的設計,沒有多餘的設計元素——不放入「現在沒用到、但預期未來會用」的想法
  • 自動化測試,讓我們有信心:一旦不小心改動了系統的既有行為,我們會知道
  • 大量修改設計的練習,所以真的該改系統時,我們不會怕到不敢動手

有了這三者——簡單設計、測試,以及持續精煉設計的態度——曲線就被壓平了。一個在「還沒寫多少程式」時只需幾分鐘的變更,在上線兩年後也只花了 30 分鐘。而作者看到的其他專案,卻花上數天或數週去做同一類決策——而不是做今天該做的事,並相信自己明天需要時修得掉

一種紀律,換一個維度#

隨著「變更成本」這個假設的翻轉,我們有機會採取一種完全不同的軟體開發途徑。它和其他途徑一樣有紀律,只是紀律落在不同的維度上

不再是「小心地早做大決策、晚做小決策」,而是——每個決策都快速做出,但每個決策都由自動化測試背書,並且隨時準備好在學到更好的設計方式時改進設計。

不過要創造這樣的途徑並不容易。我們必須重新檢視自己對「什麼構成好的軟體開發」最深層的假設。這趟旅程可以分階段走——我們先從一個故事開始,一個能錨定我們後續一切作為的故事。