谷歌軟件工程師是怎樣寫(xiě)設(shè)計(jì)文檔的?
本文介紹了谷歌的設(shè)計(jì)文檔文化,希望能幫你在軟件項(xiàng)目中做出明智選擇。
谷歌軟件工程文化的主要元素之一就是通過(guò)設(shè)計(jì)文檔定義軟件設(shè)計(jì)。在開(kāi)始項(xiàng)目編碼工作之前,軟件系統(tǒng)或應(yīng)用程序的作者會(huì)創(chuàng)建這些相對(duì)非正式的文檔。設(shè)計(jì)文檔記錄了高級(jí)實(shí)現(xiàn)策略和關(guān)鍵設(shè)計(jì)決策,并且重點(diǎn)記錄了這些決策之間的權(quán)衡考慮。
作為軟件工程師,我們的工作本質(zhì)上不是生產(chǎn)代碼,而是解決問(wèn)題。非結(jié)構(gòu)化文本,類(lèi)似設(shè)計(jì)文檔的形式,也許是在項(xiàng)目早期解決問(wèn)題比較好的工具,因?yàn)樗子诶斫?、更?jiǎn)潔,且以比代碼更高的層次來(lái)溝通問(wèn)題和方案。
除軟件設(shè)計(jì)的原始文檔外,設(shè)計(jì)文檔還實(shí)現(xiàn)了軟件開(kāi)發(fā)周期中的如下功能:
- 在早期發(fā)現(xiàn)設(shè)計(jì)問(wèn)題,而那時(shí)變更的成本還比較小
- 在組織內(nèi)圍繞設(shè)計(jì)達(dá)成共識(shí)
- 確保考慮到交叉領(lǐng)域的問(wèn)題
- 將高級(jí)工程師的知識(shí)擴(kuò)展到組織中
- 圍繞設(shè)計(jì)決策形成組織記憶的基礎(chǔ)
- 在軟件設(shè)計(jì)師的技術(shù)組合中充當(dāng)總結(jié)工具
1. 設(shè)計(jì)文檔的結(jié)構(gòu)
設(shè)計(jì)文檔是非正式文檔,因此它們的內(nèi)容不會(huì)遵循嚴(yán)格的準(zhǔn)則。一個(gè)首要原則是,針對(duì)具體項(xiàng)目可以用任何最合理的形式編寫(xiě)。
話雖如此,形成的特定結(jié)構(gòu)必定有其價(jià)值所在。
上下文和范圍
這一部分會(huì)粗略地向讀者介紹新系統(tǒng)是如何構(gòu)建的以及實(shí)際情況如何。這不是需求文檔。請(qǐng)保持簡(jiǎn)潔!我們的目標(biāo)是直接讓讀者了解最新情況,但先前的一些情況可以被推測(cè)或者能鏈接到詳細(xì)信息。這個(gè)部分應(yīng)該完全聚焦于客觀背景事實(shí)。
目標(biāo)和 non-goals
這一部分會(huì)列舉出系統(tǒng)目標(biāo)是什么,但有時(shí)候更重要的是,列出系統(tǒng)的 non-goals。注意,non-goals 并不是像“系統(tǒng)不應(yīng)該崩潰”這樣的負(fù)面目標(biāo),而是那些本可以合理地成為目標(biāo)但卻明確地選擇不作為目標(biāo)的東西。一個(gè)很好的例子是“ACID 準(zhǔn)則”;當(dāng)設(shè)計(jì)數(shù)據(jù)庫(kù)時(shí),你肯定想知道這是一個(gè)目標(biāo)還是一個(gè)非目標(biāo)。而如果這是一個(gè) non-goals,如果它不會(huì)阻礙目標(biāo)的實(shí)現(xiàn),那你仍然可以選擇一個(gè)提供它的解決方案。
實(shí)際設(shè)計(jì)
這一部分應(yīng)該從概述開(kāi)始,然后擴(kuò)展至詳情。
設(shè)計(jì)文檔適合寫(xiě)你在設(shè)計(jì)軟件時(shí)所做的權(quán)衡。把重點(diǎn)放在這些權(quán)衡上,來(lái)產(chǎn)出具有長(zhǎng)期價(jià)值的文檔。換句話說(shuō),給定上下文(事實(shí))、目標(biāo)和 non-goals(需求),設(shè)計(jì)文檔可以提供建議方案并展示為什么某個(gè)特定方案最能滿足那些目標(biāo)。
在比較正式的媒介上,編寫(xiě)文檔的目的是提供靈活性,以適當(dāng)?shù)姆绞秸故臼诸^的問(wèn)題。因此,對(duì)于如何真正地描述設(shè)計(jì)并沒(méi)有明確的指南。
盡管如此,對(duì)于大部分設(shè)計(jì)文檔來(lái)說(shuō),一些最佳實(shí)踐和重復(fù)話題都很有意義:
系統(tǒng)語(yǔ)境圖
在許多文檔中, 系統(tǒng)語(yǔ)境圖都非常有用。這樣一張圖將系統(tǒng)作為更大技術(shù)環(huán)境的一部分展示,允許讀者結(jié)合他們已經(jīng)熟悉的環(huán)境進(jìn)行理解。
https://en.wikipedia.org/wiki/System_context_diagram
系統(tǒng)語(yǔ)境圖示例
APIs
如果正在設(shè)計(jì)的系統(tǒng)暴露一個(gè) API,那么勾勒出這個(gè) API 通常是個(gè)好主意。然而,在大多數(shù)情況下,人們應(yīng)該按捺住將正式接口或數(shù)據(jù)定義復(fù)制粘貼到文檔中的誘惑,因?yàn)檫@些定義通常都很冗長(zhǎng),包含一些不必要的細(xì)節(jié),而且很快就會(huì)過(guò)時(shí)。相反,人們應(yīng)該聚焦于與設(shè)計(jì)及其權(quán)衡相關(guān)的部分。
數(shù)據(jù)存儲(chǔ)
存儲(chǔ)數(shù)據(jù)的系統(tǒng)應(yīng)該討論如何及用何種大致的形式存儲(chǔ)數(shù)據(jù)。和關(guān)于 API 的建議類(lèi)似,并且理由相同,應(yīng)該避免復(fù)制粘貼完整的模式定義。相反,要聚焦于與設(shè)計(jì)及其權(quán)衡相關(guān)的部分。
代碼與偽代碼
除了一些描述新奇算法的場(chǎng)景,設(shè)計(jì)文檔應(yīng)該很少包含代碼或偽代碼。在適當(dāng)?shù)那闆r下,可以鏈接到設(shè)計(jì)實(shí)現(xiàn)的原型。
約束度
影響軟件設(shè)計(jì)和設(shè)計(jì)文檔形狀的主要因素之一就是方案空間的約束度。
極端的一個(gè)例子就是“綠地軟件項(xiàng)目”,我們都知道目標(biāo),而且解決方案可以是任何最有意義的方案。這樣一個(gè)文檔可能涉及面很廣,但它還需要快速定義一組規(guī)則,來(lái)允許對(duì)一組可控的解決方案進(jìn)行細(xì)致研究。
另一方面,系統(tǒng)中可能的方案都定義得很好,但是完全不清楚如何將它們組合起來(lái)實(shí)現(xiàn)目標(biāo)。這可能是一個(gè)很難更改的遺留系統(tǒng),而且它不是按照你希望的樣子設(shè)計(jì)的,或者是一個(gè)程序庫(kù)設(shè)計(jì),需要在宿主編程語(yǔ)言的約束下運(yùn)行。
在這種情況下,你也許能列舉出相對(duì)容易做的事情,但你需要費(fèi)些心思將這些事情組合起來(lái),從而實(shí)現(xiàn)目標(biāo)??赡苡泻芏喾桨福珱](méi)有一個(gè)是非常好的,因此,這樣一個(gè)文檔應(yīng)該聚焦于根據(jù)所有確定的權(quán)衡點(diǎn)來(lái)選擇最佳方案。
2. 可供考慮的備選方案
本節(jié)列出了能合理實(shí)現(xiàn)類(lèi)似結(jié)果的備選設(shè)計(jì)。重點(diǎn)應(yīng)該放在每個(gè)設(shè)計(jì)所做的權(quán)衡,以及這些權(quán)衡如何導(dǎo)致選擇這個(gè)設(shè)計(jì)的決定,而這正是這個(gè)文檔的首要主題。
雖然簡(jiǎn)略介紹最終沒(méi)有被選中的方案也沒(méi)有什么,但是本節(jié)會(huì)非常明確地展示為什么被選中的方案是針對(duì)項(xiàng)目目標(biāo)的最佳方案,以及讀者可能想知道的,為什么其它方案提供的權(quán)衡針對(duì)目標(biāo)方案是不太理想的。
交叉關(guān)注點(diǎn)
在這里,你的組織可以確保像安全性、隱私性、可觀測(cè)性等跨領(lǐng)域問(wèn)題被納入考慮范圍。這些通常都是相對(duì)短的部分,解釋了設(shè)計(jì)如何影響這些關(guān)注點(diǎn)以及如何解決這些關(guān)注點(diǎn)。團(tuán)隊(duì)?wèi)?yīng)該將這些關(guān)注點(diǎn)標(biāo)準(zhǔn)化。
由于它們的重要性,谷歌項(xiàng)目需要有一個(gè)專(zhuān)門(mén)的隱私設(shè)計(jì)文檔,并且有專(zhuān)門(mén)的隱私和安全審查。雖然這些審查只需要在項(xiàng)目啟動(dòng)時(shí)完成,但最好盡早與隱私和安全團(tuán)隊(duì)接觸,以確保設(shè)計(jì)從一開(kāi)始就將這些考慮在內(nèi)。對(duì)于這些主題的專(zhuān)用文檔,中心設(shè)計(jì)文檔當(dāng)然可以只引用它們,而不是詳細(xì)介紹。
設(shè)計(jì)文檔的長(zhǎng)度
設(shè)計(jì)文檔需要足夠豐富凝練,以便忙碌的人可以真正閱讀。一個(gè)比較大的項(xiàng)目最佳長(zhǎng)度是 10-20 頁(yè)。如果你的文檔太長(zhǎng),最好將問(wèn)題分解成多個(gè)可控的子問(wèn)題。值得一提的是,寫(xiě)一份 1-3 頁(yè)的“迷你設(shè)計(jì)文檔”是絕對(duì)可行的。這對(duì)于敏捷項(xiàng)目中的增量改進(jìn)或子任務(wù)特別有幫助——你仍然可以像處理一個(gè)長(zhǎng)文檔那樣處理所有步驟,只需要保持簡(jiǎn)潔并且聚焦于一個(gè)有限的問(wèn)題集。
3. 什么時(shí)候不要寫(xiě)設(shè)計(jì)文檔
寫(xiě)設(shè)計(jì)文檔是有開(kāi)銷(xiāo)的。是否編寫(xiě)設(shè)計(jì)文檔的決定歸根結(jié)底于核心權(quán)衡,即圍繞設(shè)計(jì)、文檔、高級(jí)評(píng)審等方面達(dá)成共識(shí)的好處是否超過(guò)創(chuàng)建文檔的額外工作負(fù)擔(dān)。這個(gè)決策的核心在于設(shè)計(jì)問(wèn)題的核心是否模棱兩可——這取決于問(wèn)題的復(fù)雜度或者方案的復(fù)雜度,或者兼而有之。如果設(shè)計(jì)問(wèn)題的核心并不模糊,那么就幾乎沒(méi)有價(jià)值去編寫(xiě)一份文檔。
如果設(shè)計(jì)文檔實(shí)際上是實(shí)現(xiàn)手冊(cè),那么這就是一個(gè)設(shè)計(jì)文檔不必要的明確指標(biāo)。如果一個(gè)文檔基本上在說(shuō)“我們是如何實(shí)現(xiàn)的”,而不涉及權(quán)衡、替代方案和決策解釋?zhuān)ɑ蛘哌@個(gè)方案是如此明顯以至于不需要權(quán)衡),那么直接編寫(xiě)實(shí)際程序可能是個(gè)更好的主意。
最后,創(chuàng)建和審核一個(gè)設(shè)計(jì)文檔的開(kāi)銷(xiāo)可能與創(chuàng)建原型和快速迭代不兼容。然而,大部分軟件項(xiàng)目確實(shí)存在一些實(shí)際已知的問(wèn)題。遵循敏捷開(kāi)發(fā)方法并不是不花時(shí)間去解決實(shí)際已知問(wèn)題的借口。另外,原型構(gòu)建本身可能就是創(chuàng)建設(shè)計(jì)文檔的一部分。“我試過(guò)了,它起作用”是選擇一個(gè)設(shè)計(jì)的最佳論據(jù)之一。
4. 設(shè)計(jì)文檔的生命周期
設(shè)計(jì)文檔的生命周期的幾個(gè)步驟是:
- 創(chuàng)建并快速迭代
- 審核(可能有多輪)
- 實(shí)現(xiàn)和迭代
- 維護(hù)和學(xué)習(xí)
創(chuàng)建和快速迭代
在這個(gè)階段,你編寫(xiě)文檔。有時(shí)會(huì)和一組作者合作編寫(xiě)。
當(dāng)文檔被分享給最了解問(wèn)題領(lǐng)域的同事(通常屬于同一個(gè)團(tuán)隊(duì))時(shí),這個(gè)階段會(huì)快速演變到快速迭代期,通過(guò)他們將問(wèn)題搞清楚以及提供建議,讓文檔進(jìn)入第一個(gè)相對(duì)穩(wěn)定的版本。
雖然你肯定會(huì)發(fā)現(xiàn)工程師甚至團(tuán)隊(duì)喜歡版本控制和代碼評(píng)審工具來(lái)創(chuàng)建文檔,但是谷歌的大部分設(shè)計(jì)文檔是用 Google Docs 創(chuàng)建的,并且大量使用了它的協(xié)作功能。
評(píng)審
在評(píng)審階段,設(shè)計(jì)文檔會(huì)被分享到除初始作者和密切協(xié)作者之外的更廣泛讀者。評(píng)審可以帶來(lái)許多價(jià)值,但它們也是危險(xiǎn)的開(kāi)銷(xiāo)陷阱,所以要明智地處理評(píng)審。
評(píng)審有多種形式:比較輕量的方式是將文檔發(fā)送給(比較廣泛的)團(tuán)隊(duì)列表中,讓人們都有機(jī)會(huì)看一看。討論主要發(fā)生在文檔的評(píng)論環(huán)節(jié)。比較重的評(píng)審,是正式的設(shè)計(jì)評(píng)審會(huì)議,在會(huì)議上,作者將文檔(通常是一個(gè)專(zhuān)門(mén)的演示文稿)展示給級(jí)別較高的工程師。谷歌的許多團(tuán)隊(duì)都會(huì)為此定期召開(kāi)會(huì)議,工程師可以報(bào)名參與評(píng)審。當(dāng)然,等待這些會(huì)議的召開(kāi)會(huì)明顯減慢開(kāi)發(fā)進(jìn)度。工程師可以通過(guò)直接尋求關(guān)鍵性反饋來(lái)緩解這種情況,而不是阻礙更廣泛的評(píng)審流程。
當(dāng)谷歌是一個(gè)比較小的公司時(shí),人們習(xí)慣于將設(shè)計(jì)發(fā)送到一個(gè)核心郵件列表,高級(jí)工程師在他們閑暇時(shí)評(píng)審這些設(shè)計(jì)。這可能是一個(gè)很好的方式來(lái)處理你公司的事情。其中一個(gè)好處是,這確實(shí)在公司中建立了一種相對(duì)非正式的軟件設(shè)計(jì)文化。但是,當(dāng)公司規(guī)模擴(kuò)大到一個(gè)相對(duì)大的工程團(tuán)隊(duì)時(shí),維持集中化的方式變得不再可行。
評(píng)審帶來(lái)的主要價(jià)值是,它們提供了一個(gè)機(jī)會(huì)將組織的綜合經(jīng)驗(yàn)融入到設(shè)計(jì)中。最為一貫的是,評(píng)審階段可以確保將跨領(lǐng)域的關(guān)注點(diǎn),例如觀測(cè)性、安全性和隱私性考慮在內(nèi)。評(píng)審的主要價(jià)值不在于發(fā)現(xiàn)問(wèn)題本身,而是在開(kāi)發(fā)周期的早期就發(fā)現(xiàn)問(wèn)題,此時(shí)進(jìn)行更改的成本仍然相對(duì)較小。
實(shí)現(xiàn)和迭代
當(dāng)事情進(jìn)展到確信進(jìn)一步評(píng)審不再需要對(duì)設(shè)計(jì)進(jìn)行重大改動(dòng)時(shí),就可以開(kāi)始實(shí)現(xiàn)了。當(dāng)計(jì)劃與現(xiàn)實(shí)沖突時(shí),不可避免地會(huì)出現(xiàn)一些缺點(diǎn)、解決不了的需求、深思熟慮的猜測(cè)結(jié)果是錯(cuò)誤的等情況,并且需要變更設(shè)計(jì)。這種情況下,強(qiáng)烈建議更新設(shè)計(jì)文檔。
一般來(lái)說(shuō):如果設(shè)計(jì)的系統(tǒng)還沒(méi)有交付,一定要更新文檔。在實(shí)踐中,我們?nèi)祟?lèi)都不擅長(zhǎng)更新文檔,而且由于其它實(shí)際原因,更改通常被獨(dú)自放到新文檔中。這導(dǎo)致最終狀態(tài)有點(diǎn)類(lèi)似美國(guó)憲法附帶一堆修正案,而不是一份一致的文件。從原始文檔到這些修正文件的鏈接,對(duì)于將來(lái)嘗試通過(guò)設(shè)計(jì)文檔來(lái)理解目標(biāo)系統(tǒng)的可憐的維護(hù)程序員是非常有用的。
維護(hù)和學(xué)習(xí)
當(dāng)谷歌工程師面對(duì)一個(gè)他們從未接觸過(guò)的系統(tǒng)時(shí),他們的第一個(gè)問(wèn)題通常是“設(shè)計(jì)文檔在哪里?”。雖然設(shè)計(jì)文檔和其它文檔一樣,會(huì)隨著時(shí)間的推移與現(xiàn)實(shí)脫節(jié),但它們?nèi)匀怀3J橇私庀到y(tǒng)創(chuàng)建思想的最容易的入口。
作為作者,自我回顧并在 1 年或 2 年以后重新閱讀你的設(shè)計(jì)文檔。你做對(duì)了什么?你做錯(cuò)了什么?今天你怎么做才會(huì)做出不同的決定?回答這些問(wèn)題是一個(gè)很好的方法,來(lái)實(shí)現(xiàn)工程師進(jìn)階和隨著時(shí)間的推移提高軟件設(shè)計(jì)技能。
5. 結(jié)論
設(shè)計(jì)文檔是一個(gè)很好的方法,用來(lái)在解決軟件項(xiàng)目中最難的問(wèn)題方面提高清晰度并達(dá)成共識(shí)。設(shè)計(jì)文檔節(jié)省了資金,因?yàn)樗鼈兛梢酝ㄟ^(guò)預(yù)先調(diào)查,避免編寫(xiě)無(wú)法實(shí)現(xiàn)項(xiàng)目目的的“兔子洞”(譯者注,rabbit holes 源自《愛(ài)麗斯漫游仙境》,指通向未知世界的入口);設(shè)計(jì)文檔也損耗資金,因?yàn)閯?chuàng)建和評(píng)審設(shè)計(jì)文檔需要時(shí)間。所以,針對(duì)你的項(xiàng)目要明智地選擇!
當(dāng)考慮編寫(xiě)一個(gè)設(shè)計(jì)文檔時(shí),想一想以下幾點(diǎn):
你是否不確定正確的軟件設(shè)計(jì),是否有必要花費(fèi)前期時(shí)間來(lái)增加確定性?
與此相關(guān)的是,因?yàn)楦呒?jí)工程師可能無(wú)法審核每一次代碼變更,因此讓他們參與設(shè)計(jì)是否有幫助?
軟件設(shè)計(jì)是否模棱兩可甚至是有爭(zhēng)議的,而圍繞設(shè)計(jì)文檔在組織上達(dá)成共識(shí)是有價(jià)值的?
我的團(tuán)隊(duì)是否有時(shí)會(huì)忘記考慮設(shè)計(jì)中的隱私性、安全性、日志記錄或其它交叉問(wèn)題?
是否強(qiáng)烈需要文檔來(lái)對(duì)組織中的遺留系統(tǒng)的設(shè)計(jì)提供高層次的見(jiàn)解?
如果您對(duì)這些問(wèn)題中的 3 個(gè)及以上回答為“是”,那么設(shè)計(jì)文檔可能是開(kāi)始你的下一個(gè)軟件項(xiàng)目的好方法。