回顧Bob大叔的簡潔架構
Robert Martin 就是我們常說的Bob大叔,是碼界的骨灰級人物了,在4年前提出了所謂的簡潔架構,值得回顧反思一下,看看是否可以借鑒到微服務中呢?
大叔在文中介紹了一下幾種知名的架構思想:
- Alistair Cockburn 的Hexagonal Architecture
- Jeffrey Palermo 的 Onion Architecture
- Screaming Architecture 在Bob 大叔的博客上
- DCI 是 James Coplien, 和 Trygve Reenskaug提出的架構模型
- BCE 是 Ivar Jacobson 在其著作 Object Oriented Software Engineering: A Use-Case Driven Approach 提出的
盡管這些架構在細節上有各種各樣的不同,大叔認為是相似的,都有著相同的目標就是——關注點分離,通過關注點分離把軟件分成若干層,系統都是這樣的:
- 獨立的框架。架構不依賴于功能豐富的軟件庫,把框架作為工具而不是系統的約束。
- 可測性. 商務邏輯可以不依賴TUI, 數據庫, Web , 或其他外部元素就可以測試。
- 獨立的UI. 無需改變系統的其他部分就可以輕松地改變,例如 一個 A Web UI 換成控制臺UI,而無需改變業務邏輯。
- 獨立的數據庫.業務邏輯不與數據庫綁定,可以在各種數據庫間切換例如 Oracle 和SQL ,Mongo與 BigTable、 CouchDB等。
- 外部代理的獨立性. 事實上,業務邏輯需要簡化到無需知道外面的世界。
因此,大叔提出的簡潔架構試圖將這些架構集成為一種簡單的表達形式。
這一架構工作的最高原則就是依賴原則。這一原則說明源代碼依賴指向內部的,內圓不知道外圓的一切, 特別地,外圓中聲明的東西不需要被內圓中的代碼涉及,包括函數,類,變量以及其他的軟件實體。同心圓代表了軟件的不同領域。一般地,越深入負責,軟件的層次越多。外圓代表機制,內圓代表策略。同樣的,外圓中的數據格式也不應被內圓使用,尤其是那些被外圓中的框架所生成的數據格式,并不希望外圓影響到內圓。
實體 (Entities)
實體封裝了企業級的業務邏輯。一個實體可以是一個帶有方法的對象,或者一個數據結構和函數的集合,實體可以被企業內的多個應用使用的。如果沒有企業只是寫單個應用的話,這些實體就是應用的業務對象。他們在外部變化時改動最少,例如,不希望頁面導航的改變影響到實體對象的改變或者安全性。應用的操作性改變不應該影響實體層。
用例 (Use cases)
這一層的軟件包含了應用相關的特定業務邏輯,封裝了所以的系統用例。這些用例編排了實體之間的數據流,目標是將實體指向企業層面的業務規則。同樣不希望這一層影響到實體,也不希望這一層被外部元素所影響例如 數據庫, UI, 或其他通用框架。然而,希望應用操作的改變影響這一層的用例,如果一個用例的實現細節改變了,這一層的一些代碼一定受到影響。
接口適配器 (Interface Adapters)
該層的軟件是一組適配器的集合,這些適配器將數據轉換成用例和實體方便使用的格式,以及一些外部代理方便使用的格式例如數據庫或者Web。例如,一個包含MVC架構的圖形界面,Presenters, Views, 和 Controllers 都位于該層。models就像數據結構一些從controllers傳遞到use cases,然后從用例返回到presenters 和 views。
類似的,來自實體和用例的數據會被轉換到駐留框架,例如數據庫。這一層沒有向內的代碼來感知外部的數據庫。如果數據庫是一個SQL 數據庫的話, 那么所有SQL被限制在該層,這一層中特殊的部分處理數據庫。這一層中還有其他一些適配器轉換外部服務的數據到內部使用的用例和實體。
框架與驅動(Frameworks and Drivers)
最外層油框架和工具組成,如數據庫,Web框架等。 一般地,不需要寫大量的代碼就可以和內部的圓進行通信了。這一層細節密布,Web 是細節實現,數據是另一種細節,把他們保持在外可以減少傷害。
大叔的簡潔架構只有四層么?絕對不是的,這些圓不過是示意而言,可以遠多于4層的。但依賴原則總是適用的,最外圈總是底層的具體實現。
右下角的框圖展示了是如何跨越邊界的,描繪了Controllers 和Presenters 如何與下一層的用例通信。注意一下控制流,開始于controller, 穿過用例在presenter中執行。這也是源代碼依賴,向內執行用例。這就是通常使用的DIP,在Java中,可以通過接口和繼承關系來實現跨邊界的控制流,動態的多態性可以跨越這一架構的所有邊界。跨越邊界的典型數據是簡單的數據結構。可以使用基本結構或者簡單的數據傳輸對象,或者函數的調用參數,重要的是相互隔離。例如,很多數據庫框架都在查詢時返回一個數據集, 最好不要讓它跨邊界傳遞,它違反了依賴原則即內圓知道了外圓的事情。
回顧
通過將軟件分層,遵守依賴原則,形成內在的可測性,隔離外部的元素并具備可替代性,如此而已。
簡潔架構更像是一種指導性的原則,核心同樣是關注點分離和分層感知,沒有擺脫企業級應用架構的經典觀念。
如果聯想一下復變函數中的保角變換,這 Clean Architecture 就會變成我們熟知的有趣模樣了.......
來自:http://zhuanlan.51cto.com/art/201702/533107.htm