為什么要分層
- 支持技術復雜性與業務復雜性分離
- 分層需要明確每層的職責,單一職責,做到關注點分離
- 需要通過分層來隔離不同的關注點,以此應對不同需求的變化
- 在項目中約定每層的規范,有利於代碼的規范,更好的閱讀性
- 在代碼實現中,可以減少耦合,避免一些重復,避免一些臃腫
學習三層的過程
一層架構,二層架構
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
:表示訂單的界限上下文,一般來說每一個界限上下文就是一個微服務,要看服務划分的力度,在界限上下文中,可以根據業務選擇不同的技術架構,可以是微服務架構,也可以是三層架構
領域層
:
應用層
:
基礎設施層
:
用戶界面/展現層
:
分層總結
一:項目結構分層是有代價的,分層必定會帶來一定的工作量
二:分層的意義就是提升代碼的可維護性,閱讀性,重用性,明確職責,避免大量的重復
三:最好的架構分層,必須是基於約定的,只有遵守約定,才是好的架構
四:架構的選擇,需要根據業務和團隊的實際情況來選擇,沒有最好的架構,也沒有最差的架構,只有最適合的架構