<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          活文檔總結(jié)

          共 2776字,需瀏覽 6分鐘

           ·

          2021-04-17 11:30

          幾年前在 oreilly 看到一本叫 《living documentation》的書,可惜當(dāng)時(shí)沒讀完。

          最近圖靈出版了該書的中文翻譯版,才想起來有這么回事。。。正好最近有時(shí)間,把這個(gè)坑了幾年的東西給填上了。

          簡單來說,這本書基本可以叫 living java doc(誤。我們可以先看看日常開發(fā)中會涉及到哪些文檔:

          • 需求文檔
          • 接口文檔
          • 業(yè)務(wù)詞匯表文檔
          • 模塊業(yè)務(wù)流程文檔
          • 系統(tǒng)間交互文檔
          • 系統(tǒng)架構(gòu)文檔
          • 系統(tǒng)依賴文檔
          • 發(fā)布文檔
          • 示例文檔(tutorial)
          • 項(xiàng)目進(jìn)度文檔
          • 案例文檔
          • 匯報(bào)文檔

          要寫的類型文檔還是不少的,無論哪種文檔,都與項(xiàng)目的代碼是脫節(jié)的。所以軟件行業(yè)以往的文檔編寫方式有很多缺點(diǎn):

          • 文檔易過時(shí),因?yàn)榕c代碼是分開的,改了代碼忘改文檔是很正常的,代碼是新版本,而文檔是歷史版本
          • 文檔誤導(dǎo)人,因?yàn)榍耙粭l,功能上的修改沒有反映到文檔上,讀文檔的人會被錯(cuò)誤信息所誤導(dǎo)
          • 多余的工作量,工程師在寫完代碼之后還要再去寫一遍文檔(也可能是先寫文檔后寫代碼),基本是雙倍工作量
          • 文檔的編寫工具無統(tǒng)一的規(guī)范,大家喜歡不停地嘗試新工具,從 word 到 markdown 到 asciidoc 到 notion
          • 文檔與真實(shí)的代碼內(nèi)容是脫節(jié)的,比如在 DDD 中常講的業(yè)務(wù)詞匯表,在文檔與代碼中可能用的不是同一個(gè)詞,編碼和看文檔的時(shí)候需要腦內(nèi)額外做映射

          為了克服這些缺點(diǎn),這本書提出了一些讓代碼變 living 的方法。既然代碼和文檔分開使得兩者不易統(tǒng)一,那么我們就去追求把代碼與文檔寫在一起,并通過技術(shù)手段把文檔從代碼中生成出來。

          live_doc

          上面提到的幾種文檔,挨個(gè)來看看:

          需求文檔

          因?yàn)樾枨笞罱K會變成 BDD 測試,所以可以直接用 BDD 測試來生成這些需求文檔。

          詞匯表

          用 DDD 來做業(yè)務(wù)的話,一般可以用一些一眼就能看出含義的詞對類型和接口做注解:@DomainService,@DomainEvent,@BusinessPolicy,@AbastractFactory,@Adapter,@BoundedContext,@ValueObject。

          同時(shí)為了強(qiáng)調(diào)一些業(yè)務(wù)概念,也可以用一些自定義的詞匯,比如:@CoreConcept,@CoreBehavior,@StateMachine。

          然后通過掃描代碼,就可以直接把項(xiàng)目中的上述概念抽出,每次代碼有更新,能夠自動生成業(yè)務(wù)的詞匯表。

          自動接口文檔

          這個(gè)應(yīng)該很多人也見過了,就是類似 swagger 的項(xiàng)目??蚣茏龅暮玫钠髽I(yè)基本也都會有基于類似 swagger 的手段來做自己的接口平臺(其實(shí)做的好的沒幾個(gè))。下面是在 beego 中使用 swagger 的例子:

          swagger

          因?yàn)?Go 語言不支持 annotation,所以這些在注釋里寫的注解沒有語法層面的檢查和約束,這點(diǎn)上可能比那些支持的語言算是個(gè)弱勢。

          業(yè)務(wù)流程文檔

          在代碼中編寫相應(yīng)的流程節(jié)點(diǎn)和前后關(guān)聯(lián)節(jié)點(diǎn):

          business_process

          通過掃描代碼生成文檔:

          business_process2

          跨系統(tǒng)的交互流程:

          business_process3

          掃描生成相應(yīng)的文檔,其實(shí)和前面的差不多:

          business_process4

          除了上面這些風(fēng)格的注解,以前就已經(jīng)存在從文本生成文檔的手段,比如 plantuml,graphviz

          plantuml

          上圖這樣的 plantuml 的文本,本身就可以和代碼一起在同一個(gè)代碼倉庫中進(jìn)行管理。

          在一些業(yè)務(wù)邏輯中,涉及到難懂的邏輯,可以用 @Policy 或者 @BusinessConvention 來說明相應(yīng)的業(yè)務(wù)決策原因。

          發(fā)布文檔

          現(xiàn)在 Github 上的很多開源項(xiàng)目,已經(jīng)可以根據(jù) commit message 自動生成 release note 了。這歸功于其 commit message 本身就有一定的規(guī)范:

          commit_msg

          只要用簡單的 bash 腳本就可以將兩個(gè)版本之間的 commit message 進(jìn)行匯總,并寫出完整規(guī)范的 release note。

          國內(nèi)不少開源項(xiàng)目現(xiàn)在還是人肉寫 release note 的。

          tutorial

          新人入職需要看一些代碼范例,如果項(xiàng)目內(nèi)有寫的規(guī)范的代碼,可以專門挑出來作為例子:@Exemplar(“這個(gè)訂單流程是一個(gè)很好的 CQRS 學(xué)習(xí)示例”)。掃描代碼找到所有的 @Exemplar 注解就可以成為 tutorial 文檔了。

          穩(wěn)定文檔

          穩(wěn)定文檔指的是那些基本不怎么變動的文檔,這種文檔和代碼分開是可以接受的,為了使我們的文檔穩(wěn)定,應(yīng)該遵循一些基本的編寫原則,比如:

          • 不要帶公司的那些容易變化的信息:公司名,子公司,品牌,商標(biāo)等等
          • 如果在文檔中附帶有鏈接,應(yīng)該從非穩(wěn)定文檔指向穩(wěn)定文檔,比如你可以從自己的 blog 貼一個(gè) wikipedia 的鏈接,但是如果你去編輯 wiki 并粘貼了個(gè)人獨(dú)立 blog 的鏈接,那么可能就不太合適
          • 不要復(fù)制粘貼,盡量用鏈接引用原有內(nèi)容

          匯報(bào)文檔

          如果是項(xiàng)目進(jìn)度相關(guān)的內(nèi)容,可以用 @wip 或 @pending 之類的注解。

          如果是給老板展示的案例,老板忙的沒時(shí)間,所以可以用 @keyexample 把這些需要單獨(dú)展示的案例摘出來,

          如果是給新人學(xué)習(xí)的,除了前面說到的 tutorial,還可以有 @normalcase,@specs 等。

          架構(gòu)文檔

          一種是單模塊架構(gòu),常見的是 DDD 中的六邊形架構(gòu),可以引入 DDD 中的關(guān)鍵詞,并生成最終的文檔,比如 @HexagonalArchitecture.DomainModel,@Adapter,最終生成的文檔是下面這樣的:

          hex

          如果是跨系統(tǒng)的文檔,比如 CQRS 之類的,本身也是 Given(event),When(cmd),Then(output event) 的形式,所以用 BDD 可以生成這樣的文檔,前文有提到。

          運(yùn)行時(shí)文檔

          作者認(rèn)為 zipkin 和 dapper 這種 tracing 系統(tǒng)也是一種形式的文檔。服務(wù)發(fā)現(xiàn)系統(tǒng)中繪制出的服務(wù)依賴也是一種文檔。

          聲明式配置

          聲明系統(tǒng)配置、資源需求、依賴的,也可以生成文檔。

          從這個(gè)意義上講 k8s 的 yaml 既是文檔,也是代碼。

          架構(gòu)全景圖

          當(dāng)我們可以將所有文檔都通過掃描代碼生成之后,最好能夠?qū)⑦@些文檔管理在統(tǒng)一的架構(gòu)全景圖中,相應(yīng)的全景圖可能也可以用一些注解的輔助手段來生成,比如 @Layer(LayerType.INFRASTRUCTURE),@Repository(aggregateRoot = Customer.class)。


          瀏覽 50
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  波多野结衣亚洲一区 | 综合色亚洲| 天天插天天操天天 | 亚洲无码黄 | 黑人操比比 |