新聞中心
架構(gòu)守護(hù)代碼化,即使用易于閱讀和維護(hù)的領(lǐng)域特定語言,來描述軟件架構(gòu)守護(hù)的規(guī)則,對(duì)諸如于分層架構(gòu)、包訪問規(guī)則、包數(shù)量、繼承命名等進(jìn)行限制。

創(chuàng)新互聯(lián)建站專業(yè)為企業(yè)提供延川網(wǎng)站建設(shè)、延川做網(wǎng)站、延川網(wǎng)站設(shè)計(jì)、延川網(wǎng)站制作等企業(yè)網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)與制作、延川企業(yè)網(wǎng)站模板建站服務(wù),10年延川做網(wǎng)站經(jīng)驗(yàn),不只是建網(wǎng)站,更提供有價(jià)值的思路和整體網(wǎng)絡(luò)服務(wù)。
PS:我們這里所說的代碼化,所指的是與領(lǐng)域特定語言的方式進(jìn)行描述。
早先呢,我只是因?yàn)槭褂?Java 編寫的 ArchUnit 不支持其它語言,而在其它語言的生態(tài)里呢,也沒有這樣的合適的工具。所以呢,我就想著在 Uncode 里設(shè)計(jì)一個(gè)全新的架構(gòu)守護(hù)工具,也就是 Inherd 開源小組里的 Guarding:https://github.com/inherd/guarding/,一個(gè)多語言的架構(gòu)守護(hù)工具 —— 基于 Tree Sitter 解析各類編程語言。它設(shè)計(jì)了一套外部 DSL,其借鑒于 ArchUnit 設(shè)計(jì)的內(nèi)部 DSL 語法。
架構(gòu)的腐化:為什么我們需要架構(gòu)守護(hù)?
觀察軟件架構(gòu)在開發(fā)過程中的變化, 是一件非常有意思的事情。日常,我經(jīng)常與中大型規(guī)模公司的架構(gòu)師、技術(shù)負(fù)責(zé)人聊天,討論一些關(guān)于架構(gòu)和規(guī)范相關(guān)的問題,也是頗有意思的。當(dāng)我們聊到架構(gòu)的時(shí)候,從聊天的過程來看,都是頗為美好的。但是呢,打開代碼庫,看到代碼的分層實(shí)現(xiàn)、代碼的一些規(guī)范,我們就會(huì)發(fā)現(xiàn)結(jié)果并非如此。
美好的開始。系統(tǒng)在設(shè)計(jì)的初期,架構(gòu)師們都根據(jù)了自己的能力和經(jīng)驗(yàn),對(duì)系統(tǒng)進(jìn)行了快速的“精心”的設(shè)計(jì)。隨后,在迭代的開發(fā)中,按自己新捕獲到的知識(shí),對(duì)系統(tǒng)進(jìn)行一些調(diào)整。如果這些資深的架構(gòu)師都在編碼(間歇性的),又或者是經(jīng)常性的打開代碼庫瞧一瞧。那么,自然而然地系統(tǒng)不會(huì)出現(xiàn)過大的偏差。所以,我堅(jiān)信對(duì)于有一定規(guī)模的軟件組織來說,他們對(duì)系統(tǒng)都是有著良好的設(shè)計(jì)。
腐化的架構(gòu)。系統(tǒng)在中后期開發(fā)的過程中,先前的架構(gòu)師缺乏對(duì)于架構(gòu)的關(guān)注,又或者是經(jīng)歷了一些人員的變更,導(dǎo)致了系統(tǒng)出現(xiàn)了一處又一處的架構(gòu)不一致。當(dāng)然,其中還有一類典型的原因是,架構(gòu)相關(guān)的文檔和規(guī)范缺乏了維護(hù)。由于這一系列的種種原因,使得我們看到的系統(tǒng)架構(gòu)與這些架構(gòu)師原先的預(yù)期是不一致的。
基于上述的種種原因,在架構(gòu)上實(shí)施守護(hù)便成為諸多架構(gòu)師要考慮的問題。
為什么需要架構(gòu)守護(hù)代碼化?
程序員討論寫文檔,也討厭別人沒寫文檔。
對(duì)于架構(gòu)知識(shí)的記載、傳播和轉(zhuǎn)換,也是知識(shí)傳遞的范疇。從當(dāng)前階段來看,它存在以下幾個(gè)不同的級(jí)別:
- 系統(tǒng)本身沒有架構(gòu)文檔,文檔存在于人們的腦海里。
- 系統(tǒng)存在架構(gòu)文檔,難以理解(沒有架構(gòu)圖)。
- 系統(tǒng)存在架構(gòu)文檔,只在早期創(chuàng)建,但與實(shí)際架構(gòu)不一致。
- 系統(tǒng)的架構(gòu)文檔持續(xù)更新,但是未能及時(shí)反應(yīng)問題。
- 系統(tǒng)的架構(gòu)文檔持續(xù)更新,并使用了架構(gòu)守護(hù),以確保兩者的一致性。
- 系統(tǒng)的架構(gòu)文檔即系統(tǒng)的架構(gòu)守護(hù)測(cè)試。
上述的幾點(diǎn),我想不論是開發(fā)者,還是架構(gòu)師都是深有體會(huì)的。
文檔化的架構(gòu),需要閱讀和牢記
在架構(gòu)設(shè)計(jì)初期,開發(fā)人員對(duì)于架構(gòu)的設(shè)計(jì)往往都是經(jīng)歷過激勵(lì)的討論。所以,每個(gè)人對(duì)于架構(gòu)的形態(tài)都掌握得差不多,不需要過多的記錄也能知曉設(shè)計(jì)。沉淀下來的文案往往只是一些決策的結(jié)果,缺乏過程式的討論等。
因?yàn)檫@一種種原因,所以在過去的幾年里,我們一直在推崇『架構(gòu)決策記錄』(ADR),記錄每一項(xiàng)架構(gòu)上下文、決策和結(jié)果等相關(guān)的信息。
架構(gòu)測(cè)試的局限性
這是一個(gè)老生常談的問題,所以諸如于在 Java 世界里,人們?cè)O(shè)計(jì)出了 ArchUnit 這樣在的工具來守護(hù)系統(tǒng)的架構(gòu)。架構(gòu)測(cè)試作為架構(gòu)的文檔,缺少易讀性等等的問題。為了在多個(gè)項(xiàng)目中使用,還需要大量地復(fù)制和粘貼。
PS:在早期,我也嘗試為 JavaScript / TypeScript 世界,設(shè)計(jì)類似的架構(gòu)守護(hù)工具(即 dilay),但前端世界對(duì)于這一類的需要并不迫切。多年后,我又設(shè)計(jì)了一個(gè)新的工具,只是它已經(jīng)適用于多個(gè)語言和框架。
架構(gòu)守護(hù)即代碼:架構(gòu)文檔即測(cè)試
架構(gòu)守護(hù)代碼化,即使用易于閱讀和維護(hù)的領(lǐng)域特定語言,來描述軟件架構(gòu)守護(hù)的規(guī)則,對(duì)諸如于分層架構(gòu)、包訪問規(guī)則、包數(shù)量、繼承命名等進(jìn)行限制。
架構(gòu)守護(hù) DSL 示例
一個(gè)好的架構(gòu)文檔是個(gè)測(cè)試,并且可以執(zhí)行。如 ArchUnit 設(shè)計(jì)的內(nèi)部 DSL 語法:
- classes().that().haveSimpleNameStartingWith("Foo")
- .should().resideInAPackage("com.foo")
這句話里,描述了一個(gè)規(guī)則: Foo 開頭的類應(yīng)該放在 com.foo 包下。這也是我們?cè)谠O(shè)計(jì)架構(gòu)的時(shí)候,會(huì)設(shè)計(jì)的架構(gòu)文檔。如果我們把它翻譯成英語的話,它應(yīng)該就是:
- class(startsWith "Foo")) resideIn "com.foo"
另外一種潛在的形式可以是:
- (startsWith "Foo").class resideIn "com.foo"
從實(shí)現(xiàn)難度上來說,兩者的差別并不大,但是顯然前者更易于理解和編寫。以此類推,我們可以繼續(xù)設(shè)計(jì)一系列的規(guī)則。
其它
歡迎加入 Inherd Guarding 架構(gòu)測(cè)試與守護(hù)。
GitHub: https://github.com/inherd/guarding 。
本文轉(zhuǎn)載自微信公眾號(hào)「phodal」,可以通過以下二維碼關(guān)注。轉(zhuǎn)載本文請(qǐng)聯(lián)系phodal公眾號(hào)。
名稱欄目:架構(gòu)守護(hù)代碼化:架構(gòu)文檔即測(cè)試
鏈接地址:http://www.fisionsoft.com.cn/article/cdoeppc.html


咨詢
建站咨詢
