您現在的位置是:首頁 > 綜合
為什麼要在MVC三層架構上再加一層Manager層?
- 由 紙鶴視界 發表于 綜合
- 2021-12-16
籃球swc屬性是什麼意思
MVC三層架構
我們在剛剛成為程式設計師的時候,就會被前輩們 “教育” 說系統的設計要遵循 MVC(Model-View-Controller)架構。它將整體的系統分成了 Model(模型),View(檢視)和 Controller(控制器)三個層次,也就是將使用者檢視和業務處理隔離開,並且透過控制器連線起來,很好地實現了表現和邏輯的解耦,是一種標準的軟體分層架構。
MVC分層架構是架構上最簡單的一種分層方式。為了遵循這種分層架構我們在構建專案時往往會建立這樣三個目錄:controller、service 和 dao,它們分別對應了表現層、邏輯層還有資料訪問層。
每層的作用如下:
Controller層:主要是對訪問控制進行轉發,各類基本引數校驗,或者不復用的業務簡單處理。
Service層:主要是處理業務邏輯和事務
Dao層:負責與底層資料庫MySQL,Oracle等進行資料互動
可是隨著我們的業務邏輯越來複雜,程式碼寫的越來越多,這種簡單的三層架構的問題也越來越明顯。
MVC架構弊端
傳統的MVC分層有以下幾個很明顯的問題:
Service層程式碼臃腫
Service層很容易出現大事務,事務巢狀,導致問題很多,而且極難排查
dao層參雜業務邏輯
dao層sql語句複雜,關聯查詢比較多
為了解決這個問題,我們參考《alibaba java開發手冊》,在Service層之下再獨立出一個通用業務處理層(Manager層)
在這個分層架構中主要增加了 Manager 層,它與 Service 層的關係是:Manager 層提供原子的服務介面,Service 層負責依據業務邏輯來編排原子介面。
Manager層的特徵
在《alibaba java開發手冊》中是這樣描述Manager層的:
Manager 層:通用業務處理層,它有如下特徵:
對第三方平臺封裝的層,預處理返回結果及轉化異常資訊,適配上層介面;
對 Service 層通用能力的下沉,如快取方案、中介軟體通用處理;
與 DAO 層互動,對多個 DAO 的組合複用。
在實際開發中我們可以這樣使用Manager層
複雜業務,service提供資料給Manager層,負責業務編排,然後把事務下沉到Manager層,Manager層不允許相互呼叫,不會出現事務巢狀。
專注於不帶業務sql語言,也可以在manager層進行通用業務的dao層封裝。
避免複雜的join查詢,資料庫壓力比java大很多,所以要嚴格控制好sql,所以可以在manager層進行拆分,比如複雜查詢。
當然對於簡單的業務,可以不使用Manager層。
Manager層使用案例
這裡我們舉個例子說明一下Manager層的使用場景:
假設你有一個使用者系統,他有一個獲取使用者資訊的介面,它呼叫邏輯Service層的
getUser
方法,
getUser
方法又和
User DB
互動獲取資料。如下圖左邊展示部分。
這時,產品提出一個需求,在 APP 中展示使用者資訊的時候,如果使用者不存在,那麼要自動給使用者建立一個使用者。同時,要做一個 HTML5 的頁面,HTML5 頁面要保留之前的邏輯,也就是不需要建立使用者。
此時按照傳統的三層架構,邏輯層的邊界就變得不清晰,表現層也承擔了一部分的業務邏輯,因為我們往往會在表現層Controller中增加業務邏輯處理,將獲取使用者和建立使用者介面編排起來。
而新增Manager層以後,Manager 層提供建立使用者和獲取使用者資訊的介面,而 Service 層負責將這兩個介面組裝起來。這樣就把原先散佈在表現層的業務邏輯都統一到了 Service 層,每一層的邊界就非常清晰了。
接下來我們看一段實際程式碼說明一下Service層與Manager層如何進行區分?
@Transactional(rollbackFor = Throwable。class)public Result
上面程式碼在我們在我們採用三層架構時經常會遇到,那麼它有什麼問題呢?
上面的程式碼是典型的長事務問題(
類似的還有呼叫第三方介面
),前三步都是使用 connection 進行驗證操作,但是由於方法上有@Transactional 註解,所以這三個驗證都是使用的同一個 connection。
若對於複雜業務、複雜的驗證邏輯,會導致整個驗證過程始終佔用該 connection 連線,佔用時間可能會很長,直至方法結束,connection 才會交還給資料庫連線池。
對於複雜業務的不可預計的情況,長時間佔用同一個 connection 連線不是好的事情,應該儘量縮短佔用時間。
說明:對於@Transactional 註解,當 spring 遇到該註解時,會自動從資料庫連線池中獲取 connection,並開啟事務然後繫結到 ThreadLocal 上,如果業務並沒有進入到最終的 操作資料庫環節,那麼就沒有必要獲取連線並開啟事務,應該直接將 connection 返回給資料庫連線池,供其他使用。
所以我們在加入Manager層以後可以這樣寫:
DepartmentService。java public Result
DepartmentManager。java @Transactional(rollbackFor = Throwable。class)public void upOrDown(DepartmentEntity departmentEntity ,DepartmentEntity swapEntity){ Long departmentSort = departmentEntity。getSort(); departmentEntity。setSort(swapEntity。getSort()); departmentDao。updateById(departmentEntity); swapEntity。setSort(departmentSort); departmentDao。updateById(swapEntity);}
將資料在 service 層準備好,然後傳遞給 manager 層,由 manager 層新增
@Transactional
事務註解進行資料庫操作。
!!!更多精彩內容,請點選下方卡片並關注!!!
,https://blog。csdn。net/jianzhang11/article/details/120884260