從一層到多層架構的學習筆記
為什麼要分層
- 支援技術複雜性與業務複雜性分離
- 分層需要明確每層的職責,單一職責,做到關注點分離
- 需要通過分層來隔離不同的關注點,以此應對不同需求的變化
- 在專案中約定每層的規範,有利於程式碼的規範,更好的閱讀性
- 在程式碼實現中,可以減少耦合,避免一些重複,避免一些臃腫
學習三層的過程
一層架構,二層架構
1.最開始寫程式碼,直接在Controller
上寫業務邏輯,以及資料互動的程式碼,這樣寫在控制器上存在大量的重複程式碼,十分的凌亂,閱讀性非常差。
2.前人走後,後來的人接手,一臉蒙逼,眼花繚亂,一個方法,幾百行程式碼是基本操作,裡面包含了大量的業務邏輯,訪問DB,有的還用了檢視,儲存過程,不知道你們遇到過沒有,我是遇到過的。
3.只要經歷過維護這種程式碼的,基本上會發現。有大量的重複,可以抽離出來,許多程式碼都可以共用,於是抽象出公共的方法,大量的業務邏輯程式碼在Controller上不好維護, 把業務邏輯也抽離出來,單獨一層,把所有的業務邏輯都寫到業務邏輯層,出現了二層架構。
三層架構
1.在二層架構中,會發現,業務邏輯層中還是有大量的資料訪問的程式碼,根據單一職責,業務邏輯層應該更多關注的是,業務邏輯,而且,資料訪問的程式碼也存在許多重複的現象,於是抽出業務邏輯層中的資料訪問程式碼到資料訪問層 出現了三層架構。
2.一層到三層的出現,在我的認知裡,就是為了減少重複,避免臃腫,分離後,每一層都有自己的職責,基於約定,程式碼的閱讀性更好
3.任何軟體工程遇到的問題都可以通過增加一個第二步實現需求來解決
這句話是真的經典!
領域驅動設計的經典分層架構
領域驅動設計的經典四層架構:基礎設施層
,領域層
,應用層
,使用者介面/展現層
使用者介面/展現層
:負責向用戶展現資訊以及解釋使用者命令,是請求的入口,獲取和展示使用者需要的資料,傳遞命令給應用層
應用層
:很薄的一層,用來協調應用的活動,它不包含業務邏輯,包含控制扭轉邏輯,對外為展現層提供各種應用功能(包括查詢或命令),對內呼叫領域層(領域物件或領域服務)完成各種業務邏輯
基礎設施層
:本層作為其他層的支撐庫存在。它提供了層間的通訊,實現對業務物件的持久化,可以通過架構和框架來支援其他層的技術需求
領域層
:包含業務邏輯,是業務軟體的核心所在。在這裡保留業務物件的狀態,業務邏輯都應該包含在領域層中
光看這些概念80%的人都會懵圈,DDD中有許多的術語都需要去了解,現在我們來看一些術語對應在那一層,程式碼上怎麼體現
術語對應在那一層
由於倉儲中包含持久化,領域層不應該依賴於技術細節,通過依賴注入,所以倉儲實現部分定義在基礎設施層,倉儲的定義在領域層
應用層
:應用服務
,工作單元
領域層
:實體
,值物件
,聚合
,聚合根
,領域服務
,領域事件
,倉儲定義部分
,Process manager(Saga)事件流程管理器
基礎設施層
:倉儲實現部分
程式碼上怎麼體現
單體
1.我比較喜歡使用,解決方案資料夾給分層架構命名,在解決方案資料夾下面,按照規則建立對應的類庫
2.API介面的命名和應用服務的命名,非常重要,命名應該按照業務的用例來命名,因為單體專案的資料庫,和程式碼可能都是寫在一起的,一個業務命令可能涉及到多個上下文的互動
3.所有上下文的領域模型都在一起,必須通過約定的規則來命名,才能更好的分辨,表達業務語義,也便於以後的拆分
4.多個限界上下文的互動的通訊方式是本地訪問,需要在應用層組裝返回資料,或者在應用層使用工作單元,使用本地事務來確保成功,失敗
5.個人感覺DDD經典架構和三層架構的區別不是很大,只是DDD經典架構中有一些新的術語,把業務邏輯層,拆分為,應用層和領域層,按照OO來說,程式碼模型中應該包含業務邏輯,所以把業務邏輯層的業務都轉移到了程式碼模型裡面,DDD要求我們業務邏輯都應該包含在領域模型中,所以有些業務邏輯根據職責的劃分,放在模型裡面不合適時:就出現了領域服務
6.領域事件和Saga不是必須的,引入需要慎重考慮,一但引入,實現難度,維度難道係數,成幾何倍數增長
微服務
1.OrderBoundedContext
:表示訂單的界限上下文,一般來說每一個界限上下文就是一個微服務,要看服務劃分的力度,在界限上下文中,可以根據業務選擇不同的技術架構,可以是微服務架構,也可以是三層架構
領域層
:
應用層
:
基礎設施層
:
使用者介面/展現層
:
分層總結
一:專案結構分層是有代價的,分層必定會帶來一定的工作量
二:分層的意義就是提升程式碼的可維護性,閱讀性,重用性,明確職責,避免大量的重複
三:最好的架構分層,必須是基於約定的,只有遵守約定,才是好的架構
四:架構的選擇,需要根據業務和團隊的實際情況來選擇,沒有最好的架構,也沒有最差的架構,只有最適合的架