軟件架構編年史:整潔架構
本文轉載自微信公眾號「逸言」,作者覃宇。轉載本文請聯(lián)系逸言公眾號。
Robert C. Martin(大名鼎鼎的 Uncle Bob)于2012年在他的一篇博客中發(fā)表了整潔架構的觀點,并在一些會議上做了關于該架構的演講。
整潔架構借助了許多或熟悉或陌生的概念、規(guī)則和模式,說明了如何將它們?nèi)跁炌óa(chǎn)生出一種構建應用的標準套路。
站在 EBI 架構、六邊形架構和洋蔥架構的肩膀上
整潔架構的核心目標與端口和適配器(六邊形)架構以及洋蔥架構是一致的:
- 工具無關
- 傳達機制無關
- 獨立的可測試性
下面這張圖發(fā)表在整潔架構的博客中,揭示了該架構的總體思路:
Robert C. Martin 2012, The Clean Architecture
正如 Uncle Bob 自己在博客中所說,上面這張圖試圖將最新的架構觀點整合成一個可操作的思路。
我們來對比一下整潔架構和六邊形架構以及洋蔥架構的示意圖,看看它們在哪些方面是一致的:
外化工具和傳達機制
六邊形架構聚焦于使用接口和適配器將工具和傳達機制從應用中外化出去。這也是洋蔥架構的核心基石之一,就像圖中呈現(xiàn)的那樣,UI、基礎設置和測試全部都在示意圖的最外層。整潔架構也有完全一致的特征,UI、Web、DB 等等都在最外層。最終,所有的應用核心代碼都是獨立于框架/庫的。
依賴方向
六邊形架構中并沒有明確地告知我們依賴的方向。然而,我們可以輕易地推測出來:應用擁有接口,它們必須由適配器實現(xiàn)或使用。所以適配器依賴接口,依賴位于圓心的應用。外部依賴內(nèi)部,依賴的方向就指向圓心。在洋蔥架構的示意圖中,也沒有發(fā)現(xiàn)關于依賴方向的表示,但是,Jeffrey Palermo 在他的第二篇博客中清楚地表明了所以依賴都指向圓心。整潔架構則非常明確的指出依賴的方向是指向圓心的。它們都在架構層級引入了依賴倒置原則。內(nèi)圈不能知道外圈的任何信息。還有,當數(shù)據(jù)跨越界限進行傳遞時,數(shù)據(jù)總是以最方便內(nèi)圈使用的格式提供。
分層
六邊形架構示意圖只展現(xiàn)了兩個層次:應用內(nèi)部和應用外部。而洋蔥架構引入了 DDD 中定義的應用層次的混合:控制用例邏輯的應用服務;封裝了領域邏輯的領域服務,這些邏輯既不屬于實體也不屬于值對象;還有實體、值對象等等...和洋蔥架構相比,整潔架構保留了應用服務層(用例)和實體層,當好像漏掉了領域服務層。然而,讀過 Uncle Bob 的博客后,我們會發(fā)現(xiàn),他認為任何領域?qū)ο蠖际菍嶓w,而非只有 DDD 中的“實體”才是實體:“一個實體可以是一個擁有方法的對象,或者是一組數(shù)據(jù)結構和函數(shù)”。實際上,他為了簡化示意圖而將最中間的兩層合并了。
獨立的可測試性
三種架構風格共同遵守的規(guī)則,讓它們將應用和業(yè)務邏輯隔離了出來。這意味著任何情況下我們都可以簡單地 mock 外部工具和傳達機制,獨立地對應用的代碼進行測試,而不需要使用數(shù)據(jù)庫或 HTTP 請求。
正如我們所見,整潔架構包含了六邊形架構和洋蔥架構的規(guī)則。截至目前,整潔架構好像沒有加入什么新鮮的概念。但是,在整潔架構示意圖的右下角,還有一張小圖...
站在 MVC 和 EBI 的肩膀上
整潔架構示意圖的右下角的這張小圖說明了控制流是如何工作的。這張小圖并沒還有提供太多信息,但博客中的說明和 Robert C. Martin 的會議演講拓展了該話題。
我們在上圖的左側看到的是 MVC 中的視圖和控制器。雙實線另一層的所有形狀都是 MVC 中的模型。這些模型也代表著 EBI 架構(我們可以清楚的看到邊界、交互器和實體),六邊形架構中的“應用”、洋蔥架構中的“應用核心”,以及前面整潔架構示意圖中的“實體”層和“用例”層。
假設有一個 HTTP 請求按照控制流到達了控制器??刂破鹘酉聛頃?/p>
- 拆解請求;
- 使用相關數(shù)據(jù)創(chuàng)建一個請求模型;
- 執(zhí)行交互器(作為交互器接口的,即邊界的,實例被注入到控制器中)中的方法并將請求模型傳遞給它;
- 交互器會:
- 使用實體網(wǎng)關實現(xiàn)(作為實體網(wǎng)關接口的實例被注入到交互器中)查找相關實體;
- 編排實體之間的交互;
- 用操作的數(shù)據(jù)結果創(chuàng)建響應模型;
- 將響應模型交給展示器進行填充;
- 將展示器返回給控制器;
- 使用展示器生成視圖模型;
- 將視圖模型綁定到視圖;
- 將視圖返回給客戶端。
這里只有“展示器”的用法我有些疑問,我在項目中的實際做法和這里不太一樣。我會將某種 DTO 類型的數(shù)據(jù)返回給交互器,而不是注入一個填充了數(shù)據(jù)的展示器對象。
我通常會采用實際上是一種 MVP 實現(xiàn),控制器在其中負責從客戶端接收數(shù)據(jù)并響應它。
總結
我不認為整潔架構是革命性的,因為它實際上并沒有帶來突破性的概念或模式。
但是,我認為它是相當重要的成果:
- 它發(fā)掘了某種程度上被遺忘了的概念、規(guī)則和模式;
- 它澄清了一些實用且重要的概念、規(guī)則和模式;
- 它告訴我們?nèi)绾伟阉械母拍?、?guī)則和模式整合起來,形成一種構建復雜應用并保持可維護性的標準套路
Uncle Bob 關于整潔架構的工作總會讓我想起牛頓。引力始終是存在的,每個人都知道松手讓蘋果遠離地面的高處落下,它會落向地面。牛頓做的事情“只不過”是寫了一篇論文披露這個事實。這件事請很“簡單”,但卻讓人們開始思考它并基于它創(chuàng)造更新的想法。
換句話說,我認為 Robert C. Martin 就是軟件開發(fā)領域的牛頓[*注] !
引用來源
2012 – Robert C. Martin – Clean Architecture (NDC 2012)
2012 – Robert C. Martin – The Clean Architecture
2012 – Benjamin Eberlei – OOP Business Applications: Entity, Boundary, Interactor
2017 – Lieven Doclo – A couple of thoughts on Clean Architecture
2017 – Grzegorz Ziemoński – Clean Architecture Is Screaming
覃宇,Android開發(fā)者/ThoughtWorks技術教練//譯者,熱衷于探究軟件開發(fā)的方方面面,從端到云,從工具到實踐。喜歡通過翻譯來學習和分享知識,譯作有《Kotlin實戰(zhàn)》、《領域驅(qū)動設計精粹》、《Serverless架構:無服務器應用與AWS Lambda》和《云原生安全與DevOps保障》。