谷歌軟件工程文化的主要元素之一就是通過設計文檔定義軟件設計。在開始項目編碼工作之前,軟件系統或應用程序的作者會創建這些相對非正式的文檔。設計文檔記錄了高級實現策略和關鍵設計決策,並且重點記錄了這些決策之間的權衡考慮。

作爲軟件工程師,我們的工作本質上不是生產代碼,而是解決問題。非結構化文本,類似設計文檔的形式,也許是在項目早期解決問題比較好的工具,因爲它易於理解、更簡潔,且以比代碼更高的層次來溝通問題和方案。

除軟件設計的原始文檔外,設計文檔還實現了軟件開發週期中的如下功能:在早期發現設計問題,而那時變更的成本還比較小在組織內圍繞設計達成共識確保考慮到交叉領域的問題將高級工程師的知識擴展到組織中圍繞設計決策形成組織記憶的基礎在軟件設計師的技術組合中充當總結工具設計文檔的結構

設計文檔是非正式文檔,因此它們的內容不會遵循嚴格的準則。一個首要原則是,針對具體項目可以用任何最合理的形式編寫。

話雖如此,形成的特定結構必定有其價值所在。上下文和範圍

這一部分會粗略地向讀者介紹新系統是如何構建的以及實際情況如何。這不是需求文檔。請保持簡潔!我們的目標是直接讓讀者瞭解最新情況,但先前的一些情況可以被推測或者能鏈接到詳細信息。這個部分應該完全聚焦於客觀背景事實。目標和 non-goals

這一部分會列舉出系統目標是什麼,但有時候更重要的是,列出系統的 non-goals。注意,non-goals 並不是像“系統不應該崩潰”這樣的負面目標,而是那些本可以合理地成爲目標但卻明確地選擇不作爲目標的東西。一個很好的例子是“ACID 準則”;當設計數據庫時,你肯定想知道這是一個目標還是一個非目標。而如果這是一個 non-goals,如果它不會阻礙目標的實現,那你仍然可以選擇一個提供它的解決方案。實際設計

這一部分應該從概述開始,然後擴展至詳情。

設計文檔適合寫你在設計軟件時所做的權衡。把重點放在這些權衡上,來產出具有長期價值的文檔。換句話說,給定上下文(事實)、目標和 non-goals(需求),設計文檔可以提供建議方案並展示爲什麼某個特定方案最能滿足那些目標。

在比較正式的媒介上,編寫文檔的目的是提供靈活性,以適當的方式展示手頭的問題。因此,對於如何真正地描述設計並沒有明確的指南。

儘管如此,對於大部分設計文檔來說,一些最佳實踐和重複話題都很有意義:系統語境圖

在許多文檔中, 系統語境圖都非常有用。這樣一張圖將系統作爲更大技術環境的一部分展示,允許讀者結合他們已經熟悉的環境進行理解。

系統語境圖示例APIs

如果正在設計的系統暴露一個 API,那麼勾勒出這個 API 通常是個好主意。然而,在大多數情況下,人們應該按捺住將正式接口或數據定義複製粘貼到文檔中的誘惑,因爲這些定義通常都很冗長,包含一些不必要的細節,而且很快就會過時。相反,人們應該聚焦於與設計及其權衡相關的部分。數據存儲

存儲數據的系統應該討論如何及用何種大致的形式存儲數據。和關於 API 的建議類似,並且理由相同,應該避免複製粘貼完整的模式定義。相反,要聚焦於與設計及其權衡相關的部分。代碼與僞代碼

除了一些描述新奇算法的場景,設計文檔應該很少包含代碼或僞代碼。在適當的情況下,可以鏈接到設計實現的原型。約束度

影響軟件設計和設計文檔形狀的主要因素之一就是方案空間的約束度。

極端的一個例子就是“綠地軟件項目”,我們都知道目標,而且解決方案可以是任何最有意義的方案。這樣一個文檔可能涉及面很廣,但它還需要快速定義一組規則,來允許對一組可控的解決方案進行細緻研究。

另一方面,系統中可能的方案都定義得很好,但是完全不清楚如何將它們組合起來實現目標。這可能是一個很難更改的遺留系統,而且它不是按照你希望的樣子設計的,或者是一個程序庫設計,需要在宿主編程語言的約束下運行。

在這種情況下,你也許能列舉出相對容易做的事情,但你需要費些心思將這些事情組合起來,從而實現目標。可能有很多方案,但沒有一個是非常好的,因此,這樣一個文檔應該聚焦於根據所有確定的權衡點來選擇最佳方案。可供考慮的備選方案

本節列出了能合理實現類似結果的備選設計。重點應該放在每個設計所做的權衡,以及這些權衡如何導致選擇這個設計的決定,而這正是這個文檔的首要主題。

雖然簡略介紹最終沒有被選中的方案也沒有什麼,但是本節會非常明確地展示爲什麼被選中的方案是針對項目目標的最佳方案,以及讀者可能想知道的,爲什麼其它方案提供的權衡針對目標方案是不太理想的。交叉關注點

在這裏,你的組織可以確保像安全性、隱私性、可觀測性等跨領域問題被納入考慮範圍。這些通常都是相對短的部分,解釋了設計如何影響這些關注點以及如何解決這些關注點。團隊應該將這些關注點標準化。

由於它們的重要性,谷歌項目需要有一個專門的隱私設計文檔,並且有專門的隱私和安全審查。雖然這些審查只需要在項目啓動時完成,但最好儘早與隱私和安全團隊接觸,以確保設計從一開始就將這些考慮在內。對於這些主題的專用文檔,中心設計文檔當然可以只引用它們,而不是詳細介紹。設計文檔的長度

設計文檔需要足夠豐富凝練,以便忙碌的人可以真正閱讀。一個比較大的項目最佳長度是 10-20 頁。如果你的文檔太長,最好將問題分解成多個可控的子問題。值得一提的是,寫一份 1-3 頁的“迷你設計文檔”是絕對可行的。這對於敏捷項目中的增量改進或子任務特別有幫助——你仍然可以像處理一個長文檔那樣處理所有步驟,只需要保持簡潔並且聚焦於一個有限的問題集。什麼時候不要寫設計文檔

寫設計文檔是有開銷的。是否編寫設計文檔的決定歸根結底於核心權衡,即圍繞設計、文檔、高級評審等方面達成共識的好處是否超過創建文檔的額外工作負擔。這個決策的核心在於設計問題的核心是否模棱兩可——這取決於問題的複雜度或者方案的複雜度,或者兼而有之。如果設計問題的核心並不模糊,那麼就幾乎沒有價值去編寫一份文檔。

如果設計文檔實際上是實現手冊,那麼這就是一個設計文檔不必要的明確指標。如果一個文檔基本上在說“我們是如何實現的”,而不涉及權衡、替代方案和決策解釋(或者這個方案是如此明顯以至於不需要權衡),那麼直接編寫實際程序可能是個更好的主意。

最後,創建和審覈一個設計文檔的開銷可能與創建原型和快速迭代不兼容。然而,大部分軟件項目確實存在一些實際已知的問題。遵循敏捷開發方法並不是不花時間去解決實際已知問題的藉口。另外,原型構建本身可能就是創建設計文檔的一部分。“我試過了,它起作用”是選擇一個設計的最佳論據之一。設計文檔的生命週期

設計文檔的生命週期的幾個步驟是:創建並快速迭代審覈(可能有多輪)實現和迭代維護和學習創建和快速迭代

在這個階段,你編寫文檔。有時會和一組作者合作編寫。

當文檔被分享給最瞭解問題領域的同事(通常屬於同一個團隊)時,這個階段會快速演變到快速迭代期,通過他們將問題搞清楚以及提供建議,讓文檔進入第一個相對穩定的版本。

雖然你肯定會發現工程師甚至團隊喜歡版本控制和代碼評審工具來創建文檔,但是谷歌的大部分設計文檔是用 Google Docs 創建的,並且大量使用了它的協作功能。評審

在評審階段,設計文檔會被分享到除初始作者和密切協作者之外的更廣泛讀者。評審可以帶來許多價值,但它們也是危險的開銷陷阱,所以要明智地處理評審。

評審有多種形式:比較輕量的方式是將文檔發送給(比較廣泛的)團隊列表中,讓人們都有機會看一看。討論主要發生在文檔的評論環節。比較重的評審,是正式的設計評審會議,在會議上,作者將文檔(通常是一個專門的演示文稿)展示給級別較高的工程師。谷歌的許多團隊都會爲此定期召開會議,工程師可以報名參與評審。當然,等待這些會議的召開會明顯減慢開發進度。工程師可以通過直接尋求關鍵性反饋來緩解這種情況,而不是阻礙更廣泛的評審流程。

當谷歌是一個比較小的公司時,人們習慣於將設計發送到一個核心郵件列表,高級工程師在他們閒暇時評審這些設計。這可能是一個很好的方式來處理你公司的事情。其中一個好處是,這確實在公司中建立了一種相對非正式的軟件設計文化。但是,當公司規模擴大到一個相對大的工程團隊時,維持集中化的方式變得不再可行。

評審帶來的主要價值是,它們提供了一個機會將組織的綜合經驗融入到設計中。最爲一貫的是,評審階段可以確保將跨領域的關注點,例如觀測性、安全性和隱私性考慮在內。評審的主要價值不在於發現問題本身,而是在開發週期的早期就發現問題,此時進行更改的成本仍然相對較小。實現和迭代

當事情進展到確信進一步評審不再需要對設計進行重大改動時,就可以開始實現了。當計劃與現實衝突時,不可避免地會出現一些缺點、解決不了的需求、深思熟慮的猜測結果是錯誤的等情況,並且需要變更設計。這種情況下,強烈建議更新設計文檔。

一般來說:如果設計的系統還沒有交付,一定要更新文檔。在實踐中,我們人類都不擅長更新文檔,而且由於其它實際原因,更改通常被獨自放到新文檔中。這導致最終狀態有點類似美國憲法附帶一堆修正案,而不是一份一致的文件。從原始文檔到這些修正文件的鏈接,對於將來嘗試通過設計文檔來理解目標系統的可憐的維護程序員是非常有用的。維護和學習

當谷歌工程師面對一個他們從未接觸過的系統時,他們的第一個問題通常是“設計文檔在哪裏?”。雖然設計文檔和其它文檔一樣,會隨着時間的推移與現實脫節,但它們仍然常常是瞭解系統創建思想的最容易的入口。

作爲作者,自我回顧並在 1 年或 2 年以後重新閱讀你的設計文檔。你做對了什麼?你做錯了什麼?今天你怎麼做纔會做出不同的決定?回答這些問題是一個很好的方法,來實現工程師進階和隨着時間的推移提高軟件設計技能。結論

設計文檔是一個很好的方法,用來在解決軟件項目中最難的問題方面提高清晰度並達成共識。設計文檔節省了資金,因爲它們可以通過預先調查,避免編寫無法實現項目目的的“兔子洞”(譯者注,rabbit holes 源自《愛麗斯漫遊仙境》,指通向未知世界的入口);設計文檔也損耗資金,因爲創建和評審設計文檔需要時間。所以,針對你的項目要明智地選擇!

當考慮編寫一個設計文檔時,想一想以下幾點:你是否不確定正確的軟件設計,是否有必要花費前期時間來增加確定性?與此相關的是,因爲高級工程師可能無法審覈每一次代碼變更,因此讓他們參與設計是否有幫助?軟件設計是否模棱兩可甚至是有爭議的,而圍繞設計文檔在組織上達成共識是有價值的?我的團隊是否有時會忘記考慮設計中的隱私性、安全性、日誌記錄或其它交叉問題?是否強烈需要文檔來對組織中的遺留系統的設計提供高層次的見解?

如果您對這些問題中的 3 個及以上回答爲“是”,那麼設計文檔可能是開始你的下一個軟件項目的好方法。

原文鏈接:

https://www.industrialempathy.com/posts/design-docs-at-google/

關注我並轉發此篇文章,私信我“領取資料”,即可免費獲得InfoQ價值4999元迷你書!

相關文章