亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

java開(kāi)發(fā)MVC三層架構(gòu)上再加一層Manager層原理詳解

 更新時(shí)間:2021年10月27日 15:50:41   作者:飄渺Jam  
這篇文章主要為大家介紹了MVC三層架構(gòu)中再加一層Manager層原理的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步

MVC三層架構(gòu)

我們?cè)趧倓偝蔀槌绦騿T的時(shí)候,就會(huì)被前輩們 “教育” 說(shuō)系統(tǒng)的設(shè)計(jì)要遵循 MVC(Model-View-Controller)架構(gòu)。它將整體的系統(tǒng)分成了 Model(模型),View(視圖)和 Controller(控制器)三個(gè)層次,也就是將用戶(hù)視圖和業(yè)務(wù)處理隔離開(kāi),并且通過(guò)控制器連接起來(lái),很好地實(shí)現(xiàn)了表現(xiàn)和邏輯的解耦,是一種標(biāo)準(zhǔn)的軟件分層架構(gòu)。

MVC分層架構(gòu)

MVC分層架構(gòu)是架構(gòu)上最簡(jiǎn)單的一種分層方式。為了遵循這種分層架構(gòu)我們?cè)跇?gòu)建項(xiàng)目時(shí)往往會(huì)建立這樣三個(gè)目錄:controller、service 和 dao,它們分別對(duì)應(yīng)了表現(xiàn)層、邏輯層還有數(shù)據(jù)訪問(wèn)層。

三層架構(gòu)示意圖

每層的作用如下:

Controller層:主要是對(duì)訪問(wèn)控制進(jìn)行轉(zhuǎn)發(fā),各類(lèi)基本參數(shù)校驗(yàn),或者不復(fù)用的業(yè)務(wù)簡(jiǎn)單處理。

Service層:主要是處理業(yè)務(wù)邏輯和事務(wù)

Dao層:負(fù)責(zé)與底層數(shù)據(jù)庫(kù)MySQL,Oracle等進(jìn)行數(shù)據(jù)交互

可是隨著我們的業(yè)務(wù)邏輯越來(lái)復(fù)雜,代碼寫(xiě)的越來(lái)越多,這種簡(jiǎn)單的三層架構(gòu)的問(wèn)題也越來(lái)越明顯。

MVC架構(gòu)弊端

傳統(tǒng)的MVC分層有以下幾個(gè)很明顯的問(wèn)題:

Service層代碼臃腫

Service層很容易出現(xiàn)大事務(wù),事務(wù)嵌套,導(dǎo)致問(wèn)題很多,而且極難排查

dao層參雜業(yè)務(wù)邏輯

dao層sql語(yǔ)句復(fù)雜,關(guān)聯(lián)查詢(xún)比較多

為了解決這個(gè)問(wèn)題,我們參考《alibaba java開(kāi)發(fā)手冊(cè)》,在Service層之下再獨(dú)立出一個(gè)通用業(yè)務(wù)處理層(Manager層)

manager層

在這個(gè)分層架構(gòu)中主要增加了 Manager 層,它與 Service 層的關(guān)系是:Manager 層提供原子的服務(wù)接口,Service 層負(fù)責(zé)依據(jù)業(yè)務(wù)邏輯來(lái)編排原子接口。

Manager層的特征

在《alibaba java開(kāi)發(fā)手冊(cè)》中是這樣描述Manager層的:

Manager 層:通用業(yè)務(wù)處理層,它有如下特征:

對(duì)第三方平臺(tái)封裝的層,預(yù)處理返回結(jié)果及轉(zhuǎn)化異常信息,適配上層接口;對(duì) Service 層通用能力的下沉,如緩存方案、中間件通用處理;與 DAO 層交互,對(duì)多個(gè) DAO 的組合復(fù)用。

在實(shí)際開(kāi)發(fā)中我們可以這樣使用Manager層

復(fù)雜業(yè)務(wù),service提供數(shù)據(jù)給Manager層,負(fù)責(zé)業(yè)務(wù)編排,然后把事務(wù)下沉到Manager層,Manager層不允許相互調(diào)用,不會(huì)出現(xiàn)事務(wù)嵌套。

專(zhuān)注于不帶業(yè)務(wù)sql語(yǔ)言,也可以在manager層進(jìn)行通用業(yè)務(wù)的dao層封裝。

避免復(fù)雜的join查詢(xún),數(shù)據(jù)庫(kù)壓力比java大很多,所以要嚴(yán)格控制好sql,所以可以在manager層進(jìn)行拆分,比如復(fù)雜查詢(xún)。

當(dāng)然對(duì)于簡(jiǎn)單的業(yè)務(wù),可以不使用Manager層。

Manager層使用案例

這里我們舉個(gè)例子說(shuō)明一下Manager層的使用場(chǎng)景:

假設(shè)你有一個(gè)用戶(hù)系統(tǒng),他有一個(gè)獲取用戶(hù)信息的接口,它調(diào)用邏輯Service層的 getUser 方法,getUser方法又和 User DB 交互獲取數(shù)據(jù)。如下圖左邊展示部分。

這時(shí),產(chǎn)品提出一個(gè)需求,在 APP 中展示用戶(hù)信息的時(shí)候,如果用戶(hù)不存在,那么要自動(dòng)給用戶(hù)創(chuàng)建一個(gè)用戶(hù)。同時(shí),要做一個(gè) HTML5 的頁(yè)面,HTML5 頁(yè)面要保留之前的邏輯,也就是不需要?jiǎng)?chuàng)建用戶(hù)。

圖片

此時(shí)按照傳統(tǒng)的三層架構(gòu),邏輯層的邊界就變得不清晰,表現(xiàn)層也承擔(dān)了一部分的業(yè)務(wù)邏輯,因?yàn)槲覀兺鶗?huì)在表現(xiàn)層Controller中增加業(yè)務(wù)邏輯處理,將獲取用戶(hù)和創(chuàng)建用戶(hù)接口編排起來(lái)。

而添加Manager層以后,Manager 層提供創(chuàng)建用戶(hù)和獲取用戶(hù)信息的接口,而 Service 層負(fù)責(zé)將這兩個(gè)接口組裝起來(lái)。這樣就把原先散布在表現(xiàn)層的業(yè)務(wù)邏輯都統(tǒng)一到了 Service 層,每一層的邊界就非常清晰了。

接下來(lái)我們看一段實(shí)際代碼說(shuō)明一下Service層與Manager層如何進(jìn)行區(qū)分?

@Transactional(rollbackFor = Throwable.class)
public Result<String> upOrDown(Long departmentId, Long swapId) {
  // 驗(yàn)證 1
  DepartmentEntity departmentEntity = departmentDao.selectById(departmentId);
  if (departmentEntity == null) {
    return Result.error("部門(mén)xxx不存在");
  }
  // 驗(yàn)證 2
  DepartmentEntity swapEntity = departmentDao.selectById(swapId);
  if (swapEntity == null) {
    return Result.error("部門(mén)xxx不存在");
  }
  // 驗(yàn)證 3
  Long count = employeeDao.countByDepartmentId(departmentId);
  if (count != null && count > 0) {
    return Result.error("員工不存在");
  }
  // 操作數(shù)據(jù)庫(kù) 4
  Long departmentSort = departmentEntity.getSort();
  departmentEntity.setSort(swapEntity.getSort());
  departmentDao.updateById(departmentEntity);
  swapEntity.setSort(departmentSort);
  departmentDao.updateById(swapEntity);
  return Result.OK("success");
}

上面代碼在我們?cè)谖覀儾捎萌龑蛹軜?gòu)時(shí)經(jīng)常會(huì)遇到,那么它有什么問(wèn)題呢?

上面的代碼是典型的長(zhǎng)事務(wù)問(wèn)題(類(lèi)似的還有調(diào)用第三方接口),前三步都是使用 connection 進(jìn)行驗(yàn)證操作,但是由于方法上有@Transactional 注解,所以這三個(gè)驗(yàn)證都是使用的同一個(gè) connection。

若對(duì)于復(fù)雜業(yè)務(wù)、復(fù)雜的驗(yàn)證邏輯,會(huì)導(dǎo)致整個(gè)驗(yàn)證過(guò)程始終占用該 connection 連接,占用時(shí)間可能會(huì)很長(zhǎng),直至方法結(jié)束,connection 才會(huì)交還給數(shù)據(jù)庫(kù)連接池。

對(duì)于復(fù)雜業(yè)務(wù)的不可預(yù)計(jì)的情況,長(zhǎng)時(shí)間占用同一個(gè) connection 連接不是好的事情,應(yīng)該盡量縮短占用時(shí)間。

說(shuō)明:對(duì)于@Transactional 注解,當(dāng) spring 遇到該注解時(shí),會(huì)自動(dòng)從數(shù)據(jù)庫(kù)連接池中獲取 connection,并開(kāi)啟事務(wù)然后綁定到 ThreadLocal 上,如果業(yè)務(wù)并沒(méi)有進(jìn)入到最終的 操作數(shù)據(jù)庫(kù)環(huán)節(jié),那么就沒(méi)有必要獲取連接并開(kāi)啟事務(wù),應(yīng)該直接將 connection 返回給數(shù)據(jù)庫(kù)連接池,供其他使用。

所以我們?cè)诩尤隡anager層以后可以這樣寫(xiě):

DepartmentService.java 
public Result<String> upOrDown(Long departmentId, Long swapId) {
  // 驗(yàn)證 1
  DepartmentEntity departmentEntity = departmentDao.selectById(departmentId);
  if (departmentEntity == null) {
    return Result.error("部門(mén)xxx不存在");
  }
  // 驗(yàn)證 2
  DepartmentEntity swapEntity = departmentDao.selectById(swapId);
  if (swapEntity == null) {
    return Result.error("部門(mén)xxx不存在");
  }
  // 驗(yàn)證 3
  Long count = employeeDao.countByDepartmentId(departmentId);
  if (count != null && count > 0) {
    return Result.error("員工不存在");
  }
  // 操作數(shù)據(jù)庫(kù) 4
  departmentManager.upOrDown(departmentSort,swapEntity);
  return Result.OK("success");
}
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);
}

將數(shù)據(jù)在 service 層準(zhǔn)備好,然后傳遞給 manager 層,由 manager 層添加 @Transactional事務(wù)注解進(jìn)行數(shù)據(jù)庫(kù)操作。

以上就是MVC三層架構(gòu)上再加一層Manager層原理詳解的詳細(xì)內(nèi)容,更多關(guān)于MVC架構(gòu)Manager層原理的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

最新評(píng)論