軟體開發文件管理的簡單數學

伊藤潤二在其短篇漫畫《藏書幻影》中,描述了一位因為恐懼藏書遺失而決定將家中數十萬本書籍默記在心的書迷。不料,他記住所有藏書的內容後,卻沒有留下絲毫空間給自己的回憶與判斷力,只能終日在書堆中,眼神空洞地翻閱書頁、喃喃自語。

在軟體開發領域,我們同樣面臨對於遺忘的擔憂。需求分析、風險評估與架構決策等資訊,在開發過程中逐步累積,既是團隊經驗的傳承,也是產品應稽的依據。因此,各企業透過各式各樣的文件,紀錄程式碼以外稍縱即逝的寶貴思想與知識;對於醫療檢測產品,政府單位也提供了文件撰寫指引,詳細列出文件應具備的項目,以確保產品的安全性。

然而,市場變化與需求異動帶來的時程壓力,也使得團隊陷入開發延宕的恐慌。長期看來,文件固然能提供產品與團隊價值,但是撰寫文件往往是吃力不討好的工作,一方面它不直接改進產品功能,另一方面撰寫文件的努力不亞於軟體開發本身。因此,在迫切需要功能實現或障礙排除時,文件往往是首先被犧牲的項目。

依照我的經驗,對於如何撰寫文件的倡議,往往基於對內容的保障,未必會考量到維護齊全文件的成本。於是,團隊因為文件與開發的衝突,在棘手的情境間左右為難:要不因為害怕遺漏資訊而導致開發遲滯,又或憂懼逾期交付而造成紀錄不全。

因此,在這篇文章中,我嘗試跳脫基於儲存資訊的文件框架,加入一些專案管理的觀點,來思考解決兩者衝突的策略,從而避免過時、錯誤或不全等貶損文件價值的不利因素。

無論目標是應對稽核還是與用戶/開發者溝通,考量到文件與軟體相輔相成的作用,宜將文件視為產品的一部份,並且在規劃專案時程時,將更新文件的成本納入考慮。

根據軟體的用途和文件的性質,每個軟體迭代所需更新的文件類型和數量也會有所不同。在個人主導的開源專案中,每次軟體發布可能只涉及 README.md 和 CHANGELOG.md 的修改;但若打算申請美國 FDA 的 IVD 認證,即使是簡單的功能升級,也需要維護近十份文件(例如需求、風險、設計、測試和架構等),而且這些文件的更新必須遵循法規程序,額外增加不少行政成本。

如果團隊能在指定時間內順利完成軟體與文件更新,則可確保兩者內容及時;反之,則必有一方與進度脫節。為了避免文件過時,我們可以列出以下不等式:

$$ n \cdot t_{doc} + T_{dev} \leq T_{iter} $$

  • $t_{doc}$:更新一份文件所需要的時間
  • $n$:軟體每次迭代需要更新的文件數量
  • $T_{dev}$:軟體該次迭代的開發總時數
  • $T_{iter}$:軟體迭代週期

依據此不等式,每次軟體迭代維護文件所需的時間取決於更新的成本與頻率。假設固定迭代週期與開發時數,那麼低頻率的更新可以容忍較高的更新成本,而低成本的更新可以配合高頻率的更新。

撰寫文件的成本補僅與內容相關,也涉及過程中的調查、驗收與調整的成本;若是法規文件,還涉及更多的審查、簽核和文檔管理等手續。而文件更新的頻率則取決於其精細度,內容愈是詳細且貼近軟體底層的運作,愈有可能因為局部的變動而需要更新;反之,內容愈是抽象且概括描述軟體的架構,則能承受較多次的軟體變更。

我們可以依據這項關係來評估撰寫文件的尺度與範圍。以下是一個假想專案每次軟體迭代各層級物件的更新頻率:

Component API Change Frequency
Function 100
Class 10
Structure 1

假設這專案的迭代週期為 20 單位時間,開發費時 10 單位時間,每份文件更新需要 1 單位時間。那麼依據不等式,這軟體的文件最多能承受的更新頻率為 10 次。比照更新頻率表,若要避免文件過時,文件的內容最細只能寫到 Class 層級,而 function 層級就超出能力範圍外了。

$$ n = \frac{T_{iter} - T_{dev}}{t_{doc}}$$

透過這方法,我們可以根據軟體與團隊的特性,調整文件內容的細緻程度,來配合軟體開發的進度。然而,若文件的抽象程度越高,也意味著犧牲了一定程度的細節。在這種情況下,若仍想保留足夠的細節供往後參考該怎麼做?

原則上,文件內容是否充分取決於當下的品質與隨後的更新。首先,在開發期間透過文件指引、校稿檢查表與同儕審查等方法,可以確保文件具備必要內容並且符合團隊規範;其次,即使發現撰寫當下沒發現的錯誤,之後若能及時修正,也能補充欠缺的資訊。

這意味著文件完整性與更新文件的成本呈負相關。成本愈低,則容許修改文件的頻率也愈高,文件修訂的機會越多,改善其品質的可能性也越大。換句話說,若我們想在有限的時間內,保障文件的內容及時且完整,就需要容許較高的修訂頻率。我們可以考慮改變文件撰寫的媒介或流程,來降低不等式當中的 $t_{doc}$。

不過,將彼此相關的資訊記錄在不同的媒介可能會提升文件間的耦合程度。關聯文件越多,每次修改涉及的文件數也越多,這一方面可能增加忘記更新的機率,另一方面,也會增加每次更新時要盤查的文件數量,從而增加文件更新的成本。目前我尚未對此問題得出結論,不過可以考慮使用修改成本較低的索引文件來串接關聯文件,藉此降低主要文件的更新頻率,又能透過索引文件得知要修改的其他文件。

綜上所述,在專案時程壓力下,團隊往往面臨軟體開發與文件撰寫的衝突。若能再考慮文件應該具備的內容之餘,考量更新文件的頻率和成本,則有機會設計出能配合開發節奏的文件,避免文件過時、錯誤與不全等風險。原則上,若能降低更新文件的成本,便能承受較多次文件更新,間接確保文件的品質與完整性;若更新文件的成本較高,可以考慮調整文件撰寫的尺度,降低更新頻率,以免文件跟不上軟體開發的進度。