應用軟體開發 7 宗罪

如何提高應用軟體開發的產出

Laurence Chen
10 min readJun 26, 2022

以台灣來講,大概每一兩年,就會出現一兩則大公司發生災難級的軟體開發失敗的新聞,比方說,系統永遠上不了線之類的。實務上,不只是大公司、中小企業、即使是新創,在軟體開發遇到困難也是稀鬆平常的事。管理階層可能會認為,套用了某些方法論或是雇用了薪水很高的軟體開發人員,這些問題就可以得到控制。然而,在許多不同領域的實務往往是:「如果沒有探討發生問題的根源,就逕行套用一些『別人宣稱會有效的解決方案』,得到的成果往往有限。」畢竟,我們要如何確定,發表在媒體上的成功方法,技術成分大於公關成分呢?

在我的經驗,應用軟體開發流程裡常見的錯誤,至少有7項。不幸的事情是,這7項容易犯下的錯誤,不僅專案經理人不了解,管理階層不了解,連軟體開發人員也常常不了解。

7項應用軟體開發流程的錯誤

  1. 軟體規格書缺乏使用情境的資訊
  2. 軟體規格書缺乏對時間事件功能性驗証的描述
  3. 不合時宜的招募策略與分工方式
  4. 不知道該如何評估成效
  5. 過早的最佳化
  6. 分不清楚 simple 與 easy
  7. 盲從潮流、執著於教條

上述7項裡,1, 2 兩項屬於規畫階段的錯誤、3, 4 兩項屬於管理層面的錯誤、5, 6 兩項算是軟體工程的錯誤。最後一項錯誤有普遍性,無論是哪一個層級、哪一種專業,都很容易達成。

缺乏使用情境的資訊

我曾經被案主委託過一個軟體開發案,案主最初與我詳談的重點,全都放在使用者界面,他不斷地告訴我,使用者界面 (UI) 對他來說,超級重要,沒有好的 UI,團隊的工作是如何如何地受影響;之後的功能都可以日後再討論,先請我無論如何幫他把 UI 刻出來搭配一個簡易的 CRUD (create, read, update, delete) 功能。過了兩個月後,案主則告訴我,使用者界面不太重要,報表可以用 Excel 的格式下載即可。後來,我才理解,其實該專案最核心的價值創造部分,在於產出商業智慧 (Business Intelligence) 的報表。以這個案例來講,如果讓我重做一遍,軟體規格書最初描述的重點,自然是先放在最關鍵的報表部分。而我後來自己檢討,是我自己沒有想清楚,因為該案主就是 BI 團隊的負責人,

實務上,往往不是只靠與使用者交談,即可以取得使用情境的資訊。專注於聆聽於使用者的敘述,使用者常常傾向於訴說:『他們認為可行的解決方案,而非他們真實的使用情境。』

軟體規格書缺乏對時間、事件、功能性驗証的描述

客戶有時候會用不適用的工具,來試圖描述所需的軟體。我曾有一位客戶,總是指派他信任的下屬來寫規格書給我。這些規格書往往是用 PowerPoint 寫的,對使用者界面的部分,描述過多的實作細節,卻完全沒有描述遠比使用者介面更重要的:時間, 事件, 功能性驗証。我拿到規格書之後,看到許多的 UI 元件,UI 元件描述了它們該做什麼,卻沒有明確地講清楚先後次序與 UI 事件發生彼此的依賴關系,這就是缺乏時間與事件的描述。

再談一個缺乏「功能性驗証」的例子,我的一位會計師客戶請我設計一個 UI 元件,該元件的功能是:『提供一個選項,讓報表可以產出,最近一年的某財務資訊報表。』等到驗收軟體時刻,我們雙方才同時搞懂:『一年是 365 年這件事,只算是 75% 正確,因為閏年是 366 天。』

不合時宜的招募策略與分工方式

有一些中小企業認為,既然大公司招募軟體工程師考 codility 或是 leetcode ,我們也應該如此做,才能招募到能力優秀的軟體工程師。然而,大公司由於開出的薪資偏高,一旦有新職缺,應徵者相當多,所以先用白板考的方式,快速篩掉大量的應徵者,以集中有限的資源來面試剩下來高可能性的應徵者。中小企業如果沒有理解上述的方式是一種權宜之計,而單純地認為,善長白板考就等於專業能力,很可能會在招募上遇到許多挫折。

「不考演算法的話,如何確保工程師可以寫出效能夠好的程式?」曾經有客戶如此質疑我。

「在 ACM 比賽時,探討的效能著重於 Big O complexity 。然而,實務中應用軟體開發,需要探討的效能問題,十之八九不是 Big O 而是 IO 。」我如此地回答了他。

同樣的道理,軟體開發,大公司因為人手充足,總是設法組成 6、7 人的開發團隊,比方說,拆成前端、後端、專案管理、運維、測試等,這也不代表中小企業就應該仿效。實際上,在不過分犧牲軟體品質的前提之下,一人身兼多職,反而容易有高產出。將工作做精細地拆分,也許找人相對容易,作工也可以更加精細,另一方面,拆分地愈細,專業人士往往就離最終的產出愈遠,因為每個人都只專注於分割到自己手上的工作。拆分工作,妥善地協調,並得到有效的產出,這往往需要一種中小企業很容易缺乏的關鍵能力:管理

不知道該如何評估成效

在『彼得原理』對於「不知道該如何評估成效」導致的狀況,有獨到的見解:不適任的主管在評估下屬時,是以下屬在工作投入 (input) 的程度來評估;因為該主管已經不適任了,所以他也不了解什麼是正確、應然的工作產出 (output)。

在我個人的經驗,就算是了解工作產出的主管,在評估成效時,常犯下的錯誤,則是片面評估、或是見樹不見林。片面評估是指:只評估了一個面向、而沒有評估所有必須評估的面向。比方說,只著重軟體準時交付,而忽略了長期而言是否可以迭代開發。

見樹不見林則是指:沒有把整個系統納入思考、沒有全局觀。以資訊安全為例,我曾看到一種情況,某些組織在委外軟體時,對於軟體要求一些 ISO 的認証。然而,該組織的員工卻極度缺乏資安觀念。於是,面對真正的駭客,使用基本的社交工程招式就可以騙取密碼。

曾經有一個客戶詢問我,「要如何可以提高軟體交付時程的能見度?」我反問了客戶一個問題,「貴公司在開發新的軟體功能時,是否會先設法達成 walking skeleton, 再繼續前進?」開發軟體的時程,總是有很多的不確定性,比方說,為了處理 A 資料格式,於是使用了 B 函式庫。每次引入一個新的函式庫,就等同於引入了一個新的不確定性。再加上本來處理業務邏輯也可能有一定程度的不確定性,不確定性逐步累加,準時交付就變成了一種量子現象。估時不準確,這是軟體開發的普遍現象,然而,成熟的軟體開發團隊會傾向於 fail fast and fail early ,讓不確定的因素,可以早期被發現,再重新估時。一旦完成了 walking skeleton ,至少因為引入函式庫或是與外界溝通造成的不確定性已經移除了。

過早的最佳化

有的軟體開發人員認為,所謂『過早的最佳化』只是指效能改進而言。只要效能改進等到系統完成再來做,就不會造成『過早的最佳化』。我則持另一種看法,我認為如果只需要達成 60分的應用卻採用了可以達成 95分的技術,都可以視為是『過早的最佳化』,比方說:

  1. 複雜的軟體架構,比方說: microservices、甚至是 kubernates
  2. 極致的使用者體驗,比方說:mobile application 或是 SPA (single page application)
  3. 過多的效能、可擴展性 (scalability),比方說:NoSQL 或是 IaaS
  4. 100 % 的測試覆蓋、複雜的型別系統

一旦做了過早的最佳化,相當於在只需要做到 60 分的項目上,不停地投注 95 分的心力,軟體開發自然快不起來。

分不清楚 simple 與 easy

在軟體工程的老生常談是要把系統做得簡單 (simple)。然而,簡單 (simple) 與容易 (easy) 這兩個概念實在是非常容易混淆。也因此,實務上,很多工程師做到了 容易,卻以為自己達成的是簡單。easy 是軟體開發者對難度的感受,這個因人而異,而且常常跟熟悉、熟練度有關。simple 則是指系統內部,是否有相對清楚、不交錯的依賴關系。easy 是一種主觀的感受,而 simple 則是一種客觀的性質。

以常見的 OTLP 應用來舉例:

  1. 直接手寫 SQL,這是 simple 卻不 easy 的解決方案
  2. 透過 ORM (Object Relational Mapping) 之類的工具來產生 SQL ,則是 easy 但是不 simple 的解決方案。

對於不喜歡寫 SQL、對 SQL 不熟悉的開發者,ORM 可以讓這些軟體開發者在不甚了解 SQL 的前提之下,在系統初期的階段,快速地前進,這會讓開發者覺得非常的 easy 。然而,透過 ORM 產生的 SQL 查詢 ,卻常會在一些特定的案例會產生效能低下的查詢。於是,採用了 ORM 之後,造成的結果是,要用 ORM 來建構正確可用的系統,至少必須依賴於四件事:

  1. 軟體開發者對 ORM 的了解
  2. 軟體開發者對 SQL 的了解
  3. 軟體開發者對 ORM 相對少見例外的充分了解
  4. 軟體開發者對 ORM 難以處理例外發生時,該怎麼處理的充分了解

最糟的事情莫過於,即使如此,如果系統持續演進,系統很可能還會更加複雜。一次又一次為了解決 ORM 不足之處上加上的補丁設計,又會再一次地成為新的依賴。

盲從潮流、執著於教條

盲從潮流,有時候跟大公司強大的行銷能力頗有關系。

比方說,像大公司想要新創公司都用 IaaS (Infrastructure as a Service) 的雲端服務,二話不說,就先送新創小公司一兩年的免費額度。然而,問題出在,要妥善地使用 IaaS 往往比要使用 PaaS (Platform as a Service) 需要更多的運維人力,對於新創小公司來講,省了一兩年的雲端伺服器費用,往往是付出數倍的運維管理成本。

另一種情況,大公司想要推廣自家的某某技術來強化自己在人才招募上的優勢,比方說,某種程式語言,於是就讓一些 IT 媒體做一些專訪,美其名為專訪,實則為置入性行銷。於是,媒體大力報導的軟體技術每年不停地更替,像是永無休止一般。軟體工程師與需要招募軟體工程師的雇主,也容易誤認為,採用新的技術棧就是創新能力的表現,因而雙方都不停地追趕新的技術棧。但是,採用這些技術棧真的就可以提高生產力嗎?

該怎麼避免這些錯誤?

每個軟體開發團隊的任務特性不同,不會有一種方法適用於各種團隊。要避免上述的 7 項錯誤,需要在採用某一特定的工作方法之前,先仔細地思考任務的應用情境,與某一工作方法是否相契合。

對於新創公司、中小企業、又或是交付時程極為緊迫的軟體開發團隊而言,通常可以滿足下列的假設:

  1. 客戶的需求常常變動、使用者常常難以在最初把需求徹底地講清楚
  2. 使用者介面的極致體驗、軟體運行的效能、軟體是否容錯這些事的重要性,低於軟體的準時交付與正確性。

如果上述兩項假設都滿足的話,我通常建議客戶採用下列的技術棧與方法論,來做一般 (OLTP) 應用軟體開發的預設選項 (default option)。這些技術棧與方法論,保守地評估,已足以解決 90% 的應用情境。

  1. 軟體規格採用 event modeling method
  2. 評估成效採用 the four key metrics
  3. 前端採用 htmx
  4. 後端採用 Clojure
  5. 資料庫採用 Postgres 或是 XTDB (如果需要時間迴溯與 bitemporality 的功能的話,可以考慮 XTDB)
  6. 分散式的應用,採用 Actor-based 的方式來開發,而非 Microservices

又或者是,你也可以考慮連絡

--

--

Laurence Chen

IT 顧問、講者、作家。喜歡快速迭代 (fast iteration) 與提高產出。 著作:「從錯誤到創新」 https://leanpub.com/errors_to_innovation/ 網站:https://replware.dev/