軟體開發宣言:請保持簡潔
本文要點:
- 複雜度是軟體公司成長和盈利的最大障礙。
- 開發成本隨程式碼庫的複雜度增加呈指數增長。
- 在進度和簡潔之間做選擇是一個錯誤的二分法。對簡潔的投資就是對進度的投資。
- 很少有高管認識到複雜度的代價,因為他們不瞭解其銷售的產品的性質。
- 軟體是一種比較特殊的產品,它混合了產品和服務,帶有非常獨特的質保。
複雜度是公司原始碼的特徵之一。通常與以下幾種情形有關聯:
- 考慮不完善的架構,即資料在應用程式元件之間傳遞的方式。
- 大量的冗餘程式碼(不再使用的程式碼)。
- 程式碼設計沒有考慮模式的應用,比如面向物件設計和依賴注入等。
- 儲存資料的結構維護得很差,比如未使用的列或不再使用的表仍然儲存在關係資料庫中。
- 註釋文件不足,程式碼難以閱讀,開發人員很難維護或二次開發。
軟體開發人員對這種失敗有自己的稱謂,而我們稱之為技術債。沒有人願意談論它,但正是這些我們本應該注意的問題,它們一點點累積起來,在不知不覺中讓公司的產品開發變得苦不堪言。公司原本只需要幾天或幾周就能推出的特性,現在也變成了幾個月。
簡潔是複雜的對立面。當代碼組織良好、邏輯簡明並且易於閱讀時,它就顯示出簡潔性。需要指出的是,複雜和簡潔跟程式碼行的數量沒有直接關係。一個非常大的程式碼庫(例如,谷歌大約有 20 億行程式碼)可能並沒有很複雜,而一個小的程式碼庫也可能一點都不簡潔。
複雜度問題
複雜度是阻礙軟體公司成長和獲利的最大障礙之一。開發成本隨著複雜度的增加而呈指數性增長。之所以存在這種指數關係,是因為隨著軟體產品變得越複雜,公司需要更多的開發人員對其擴充套件和維護;而隨著開發人員數量的增加,公司的管理人員也越來越難掌控複雜度。
那為什麼還有這麼多軟體公司允許複雜度來危害產品程式碼呢?畢竟這其中的很多公司不乏聰明而勤奮的員工,甚至他們的生計也依賴於軟體本身。很少有高管(天使投資人和風險投資家就更少了)能夠認識到複雜度的代價,這是因為他們不瞭解其銷售的產品的性質。軟體是一種比較特殊的產品,當你銷售軟體的時候,你實際上是在銷售一種混合了產品和服務並帶有獨特質保的東西(詳見下文A 還是 B )。
軟體公司的管理人員,甚至早期的工程師,都是畢業於商學院。他們喜歡從銷售、市場營銷和微觀經濟學的角度來看待自己所處的行業。他們也深信“做第一個”的教條,或者說,速度優勢。
做第一個固然好,但做第一名更好。早期的搜尋引擎先驅雅虎就很好地體會到了這個教訓。雅虎雖然是第一個推出搜尋服務的公司,但谷歌作為後來者,憑藉更好的演算法、商業模式和領導團隊很快超越了前者。當然很多時候,一家公司可能還沒有來得及入場就已經被淘汰。例如,現在很難想象有新公司要挑戰谷歌在搜尋領域的地位。但是,爭奪行業主導地位的競賽是一場馬拉松,而不是短跑,而且賽道上最初的幾圈對長期結果幾乎沒有影響。
通過要求中層管理人員儘快將產品推向市場,偏執地專注於速度優勢可能會危及公司的生存。與此同時,像敏捷這樣的工作流管理方法(經常被誤解和執行不力)可能會把問題複雜化,因為它們注重速度的實踐制度化,而簡潔將成為背後的犧牲品。公司中往往只有軟體開發人員能夠唯一意識到這一點。
的確,軟體公司不能從仍在開發的產品中獲利,但是,當管理人員偏重於釋出的速度而不是基礎程式碼完整性的時候,投資資本和使用資本的回報將會有很大的風險。複雜度的成本顯然比加速釋出日期節省的成本更高。
諷刺的是,在進度和簡潔之間做選擇是一種錯誤的二分法。對簡潔的投資其實也是對進度的投資,因為簡潔可以將軟體產品更快地推向市場,然後更有效地維護和增強它們。它還是智慧財產權的源泉,也是一種一旦失去就幾乎不可能重新獲取的競爭優勢。
芝諾悖論
在著名的阿基里斯悖論裡,快捷的阿基里斯必須追上一隻始終在他前面的笨重的烏龜。古希臘哲學家芝諾認為,因為追逐者必須首先要追上被追趕者的起點,所以阿基里斯必須在每次縮排距離的同時首先要抵達烏龜的起點,這樣儘管領先越來越少甚至無窮小,但烏龜將始終保持領先。
芝諾悖論有助於解釋為什麼你的公司也可能是那個追趕烏龜的阿基里斯。當原始碼變得複雜時,新增新程式碼會非常困難,舊程式碼也幾乎不可能被除錯。對簡潔有序比較執著的開發人員會變得沮喪,直到最終放棄。當然並不是所有的開發人員都會離開,而且這也會是一個緩慢的過程。然而,影響還是會逐漸蔓延開來,公司發展速度會隨著他們的離開而變慢,招聘和入職的相關成本也會增加。
此外,你將很難找到合適的替代人員。因為在當今的社交網路世界中,你公司的程式碼狀態對開發人員社群基本上是透明的,而它正是你從中招聘開發人員的地方。迫不得已的情形下,你可以僱傭新的工程師來處理這些複雜的程式碼,而他們所需要的薪酬要遠高於市場平均水平。與此同時,特性的增加以及複雜度的進一步提高會需要更多的工程師。所以死亡螺旋會一直繼續。
我工作的軟體公司也面臨著複雜度的問題。同其他公司一樣,我認為我們公司沒有清楚地認識到困境的前因後果,我們轉而將業務外包(包括在岸和離岸業務),希望能改善這種狀況。但是複雜度是一個不能外包的問題,外包只會讓問題變得更糟,因為外包公司以及他們僱傭的承包商更願意擴大知識面,並增加程式碼的複雜度,他們這樣才能獲取更多的經濟利益。
A 還是 B?
設想一下:假設汽車製造商之間的競爭以及二手車庫存過剩大大抑制了新車銷量。因此,一家高階車製造商的高管們做出了大膽的迴應:永久質保。經過仔細研究分析,公司決定提高標價 20%,他們不單為客戶提供同樣高質量的汽車,還承諾在整個保修期(比如說四五年)內對車輛承擔全部責任,包括所有預定的維修,以及改裝載入新車型才有的新功能。
讓我們通過兩種情形對這一舉措進行評估:
- 情景 A:該公司的車輛設計得很好。它的工程師充分利用了模組化和開放式架構,因此新增特性或替換故障元件變得非常容易。新舉措不僅在新車收入方面增加了 20%,而且公司經銷商的銷售和服務部門也比以往更加忙碌。與此同時,環保人士、政府機構和司機都稱讚該公司保養車輛的效率和安全效能。車主也高興,車輛在保修期結束後的轉售價值相當高,變相降低了新車的購買成本。這項創新很快就被宣佈為一項勝利。在幾年的時間裡,其他製造商也在試驗他們自己的永久質保專案,但是因為他們本身設計上的複雜性,質量很難保證,最終使這項試驗變得前途迷離。
- 場景 B:儘管該公司的汽車功能豐富,效能良好,但是其內部設計複雜且雜亂無張。自該計劃推出以來,新車銷售收入增長了 20%,這在一定程度上抵消了正在進行的維護和功能增強的成本。但隨著每一次持續地改進,履行保修的困難和成本開始逐步升級。永久質保專案剛剛過了兩年,這些成本就變得不可維護,汽車製造商也撤回了報價。但是,公司仍然需要履行對已有客戶的義務。高管們估計損失將近 10 億美元,並面臨是否繼續經營的艱難決定。
現在你可以認識到永久質保在汽車行業裡的不切實際之處。但如果你是一家軟體公司的主管,你應該意識到你已經提供了一個永久質保。唯一的問題是,你是在場景 A 還是場景 B 下工作?
簡潔開發宣言
這是一個改進軟體開發的宣言,或者更謙虛地說,這不過是請求尊重常識。如果你的組織還沒有越過複雜度的臨界點,那麼儘快按照下面的處方進行補救。它是一張路線圖,可以讓你降低軟體的複雜度,顯著降低開發成本,縮短上市時間;它又是一個可維持的開發過程,既能保證公司的未來,又能把你的競爭對手甩在身後。
學習。複雜度只能自上而下地修復。領導者需要投入時間來理解軟體開發生產線上發生的一切。這需要多長時間?當你意識到相對於程式碼的簡潔性而言上市時間反而是次要因素的時候,你就已經完成目標了。
領導力。通過工程管理的等級來逐層強調簡潔性,這樣你的組織就會圍繞一套新的價值觀來保持一致。溝通這個計劃的戰略價值。
重新評估。評估公司是否真地需要像敏捷開發這樣的工作流管理方法,還是隻需要一種強調設計質量而非開發進度的替代方法。
有策略地招聘。招聘那些熱愛簡潔的開發人員。這些人通常是寫實際程式碼最慢的人,他們喜歡花很長的時間來分析需求和構建程式碼的可維護性、執行時間、記憶體消耗和資料儲存方面的最佳解決方案。他們也會樂於記錄自己的工作並與同事分享。
知識管理。產品程式碼才是公司的生命線,需要在整個組織中貫徹落實這個理念,而不僅僅侷限在一個部門。維持一個分散的知識結構意味著在知識共享上需要投入更多的時間,但是這也可以讓你根據不斷變化的業務需求來快速重新部署工程師。
腳踏實地。現在我們已經使用了一些很棒的技術和工具來編寫、測試、部署和監控軟體。其中大多數都是重複的,只帶來了增量收益和高轉換成本。我們需要專注於其中的一小部分,並且優先要考慮工程師已經掌握的技術。
度量進展
我們可以通過追蹤你僱傭的工程師數量和他們的失誤率來度量公司在反覆雜度過程中的進展。如果你不在高科技行業,但你工程部門的規模增速快於線上銷售,那麼這是一個非常糟糕的訊號;如果你在一家軟體公司,但面臨員工的大量流失,這也很糟糕。原始碼簡單的公司會有一個相對小而穩定的工程師團隊,而且這個團隊會隨著產品功能的進步而緩慢成長。相反,如果是一個被軟體複雜度所困擾的公司,它會發現自己在不斷地招人,飛速奔跑氣喘吁吁地追逐一隻烏龜。
關於作者
Paul Merlyn是 Consensus Corp 的全棧工程師和思想領袖,Consensus Corp 是 Target 的數字啟用子公司。Paul 還是一名活躍的企業家,他創辦了 Fynancially(一家致力於金融服務行業民主化的企業)、Abridg 社交網路以及 National Mediation Training Registry(國家調解培訓註冊中心)。他信奉,“JavaScript 正在吞食 Java 的午餐,並且將在晚餐時間毫不猶豫地統治世界”。
檢視英文原文:https://www.infoq.com/articles/simplicity-manifesto-development