溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

淺談java領(lǐng)域模式分層實(shí)現(xiàn)

發(fā)布時(shí)間:2020-06-21 20:55:12 來源:網(wǎng)絡(luò) 閱讀:1086 作者:青羽的瘋狂 欄目:編程語言

隨著軟件開發(fā)技術(shù)不停地迭代更新,現(xiàn)在的系統(tǒng)基本上實(shí)現(xiàn)了由表示、邏輯一體化到分層模式的轉(zhuǎn)變。
一個(gè)好的層次劃分不僅僅可以使代碼結(jié)構(gòu)更加清晰、增添代碼可讀性。同時(shí)也使得項(xiàng)目分工更加明確,維護(hù)更為便利。
而我要介紹的是在java開發(fā)領(lǐng)域中,面向?qū)ο蟮姆謱幽J?領(lǐng)域模型分層。
領(lǐng)域模型分層最主要的工作就是分離領(lǐng)域,分離領(lǐng)域就是將領(lǐng)域?qū)ο笈c系統(tǒng)中的其他功能分離,從而避免將領(lǐng)域概念和其他只與軟件技術(shù)相關(guān)的的概念相混淆,其最終目的是為了讓對象更專注于邏輯處理而無需關(guān)注其他的事物。
領(lǐng)域模型設(shè)計(jì)書籍曾描述過領(lǐng)域模型可分為4層,分別是
1、用戶界面層
負(fù)責(zé)向用戶顯示信息和解釋用戶指令
2、應(yīng)用層
定義軟件要完成的任務(wù),并指揮表達(dá)領(lǐng)域概念的對象來解決問題
3、領(lǐng)域?qū)樱P蛯樱?br/>負(fù)責(zé)表達(dá)業(yè)務(wù)概念,業(yè)務(wù)狀態(tài)信息以及業(yè)務(wù)規(guī)則
4、基礎(chǔ)設(shè)施層
為各層提供通用的技術(shù)能力,為應(yīng)用層傳遞消息,為領(lǐng)域?qū)犹峁┏志没瘷C(jī)制。
在結(jié)合實(shí)際的開發(fā)經(jīng)驗(yàn)與書本的知識(shí),認(rèn)為在開發(fā)過程中可落地成如下幾層:
Controller層【用戶界面層】、Service層【應(yīng)用層】、Action層【應(yīng)用層】、entity層【領(lǐng)域?qū)印?、DAO層【基礎(chǔ)設(shè)施層】。
其層與層的關(guān)系如下圖:
淺談java領(lǐng)域模式分層實(shí)現(xiàn)
為了更好的理解上述分層架構(gòu),舉個(gè)栗子來說明一下。
先設(shè)定一個(gè)場景:
有一家服裝店,店里有店長和多個(gè)導(dǎo)購。該店有一批會(huì)員,為了更好的服務(wù)會(huì)員,店長需要將會(huì)員分配給導(dǎo)購,讓導(dǎo)購服務(wù)自身的會(huì)員。
待實(shí)現(xiàn)功能:給導(dǎo)購分配會(huì)員
淺談java領(lǐng)域模式分層實(shí)現(xiàn)

  • Controller層【用戶界面層】:負(fù)責(zé)與界面或其他系統(tǒng)的對接,相當(dāng)于一個(gè)系統(tǒng)的門戶。所有其他非本系統(tǒng)的用戶都應(yīng)該先將請求提交給Cotroller層。

    作用:
    1、負(fù)責(zé)接待外來用戶,并將請求傳遞給下一層
    2、校驗(yàn)請求的合法性【如:判斷用戶合法性,請求參數(shù)合理性】
    3、相應(yīng)用戶請求【系統(tǒng)將請求處理完畢后,將返回的結(jié)果組合成用戶想要的結(jié)果】

代碼:
package com.csosm.layout.controller;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.collections.MapUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.csosm.layout.service.EmployeeService;
import com.google.common.base.Splitter;
/**
 * 用戶界面層,為前端或其他系統(tǒng)用戶提供訪問接口
 * @author bear
 *
 */
@RequestMapping("/employee")
public class EmployeeController {

       /**
        * 對外提供添加為導(dǎo)購添加會(huì)員接口
        * @param requestMap 請求數(shù)據(jù)(memberIds:【注:會(huì)員ID集合,會(huì)員ID間以逗號(hào)隔開】,employeeId:【注:導(dǎo)購ID】)
        * @param request
        * @return 視圖
        */
       @RequestMapping(value = "/members/add.json")
       @ResponseBody
       public Map<String,Object> addMembers(@RequestBody Map<String, String> requestMap,
             HttpServletRequest request){
              //進(jìn)行請求參數(shù)校驗(yàn)
              if(!requestMap.containsKey("memberIds")&&!requestMap.containsKey("employeeId"))
                    throw new IllegalArgumentException("請求參數(shù)缺少[memberIds]或[employeeId]");
              //從請求參數(shù)中提取會(huì)員ID集合
              List<Integer> memberIds = Splitter.on(",").splitToList(MapUtils.getString(requestMap, "memberIds"))
                           .stream().map(x -> Integer.parseInt(x)).collect(Collectors.toList());
              //從請求參數(shù)中提取導(dǎo)購ID
              Integer employeeId = MapUtils.getInteger(requestMap, "employeeId");
              employeeService.addMembers(employeeId, memberIds);
              return null;//自行定義返回成功
       }

       @Resource
       private EmployeeService employeeService;

}`
Service層【應(yīng)用層】:對接Controller層,為Controller層的每一個(gè)請求提供對應(yīng)的接口,為下一層Action層做數(shù)據(jù)準(zhǔn)
作用:
1、將controller傳遞的數(shù)據(jù)還原成對象
2、進(jìn)行跨對象邏輯處理
代碼:
package com.csosm.layout.service;
import java.util.Collection;
import java.util.Objects;
import javax.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import com.csosm.layout.action.EmployeeAction;
import com.csosm.layout.action.MemberAction;
import com.csosm.layout.entity.Employee;
import com.csosm.layout.entity.Member;
/**
 * Employee的應(yīng)用層,可跨對象操作
 * @author bear
 *
 */
public class EmployeeService {

      /**
       * 為導(dǎo)購添加多個(gè)會(huì)員
       * @param employeeId 導(dǎo)購ID
       * @param memberIds 會(huì)員ID
       */
      public void addMembers(Integer employeeId,Collection<Integer> memberIds) {
             Objects.requireNonNull(employeeId,"導(dǎo)購ID[employeeId]不能為空");
             if(CollectionUtils.isEmpty(memberIds)) return ;//如果傳入的會(huì)員ID為空,則返回
             Employee employee = employeeAction.getById(employeeId);
             Collection<Member> members = memberAction.getByIds(memberIds);
             if(CollectionUtils.isEmpty(members)) return ;//如果根據(jù)會(huì)員ID獲取的會(huì)員數(shù)目為空,則返回
             employeeAction.addMembers(employee, members);
      }

      @Resource
      private EmployeeAction employeeAction;
      @Resource
      private MemberAction memberAction;
}
* Action層【應(yīng)用層】:該層只對Entity層負(fù)責(zé),是Entity層對外提供的接口
作用:
1、為系統(tǒng)內(nèi)部提供操作實(shí)體的接口
2、調(diào)用dao層持久化對象
代碼:
package com.csosm.layout.action;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import javax.annotation.Resource;
importorg.apache.commons.collections.CollectionUtils;
import com.csosm.layout.dao.EmployeeDAO;
import com.csosm.layout.entity.Employee;
import com.csosm.layout.entity.Member;
/**
 * 獨(dú)屬于Employee對象的應(yīng)用層
 * 盡量使用對象
 * @author bear
 *
 */
public class EmployeeAction {
      /**
       * 給導(dǎo)購添加多個(gè)會(huì)員
       * @param employee 導(dǎo)購
       * @param members 多個(gè)會(huì)員
       */
      public void addMembers(Employee employee,Collection<Member> members) {
             Objects.requireNonNull(employee,"導(dǎo)購[employee]不能為空");//校驗(yàn)導(dǎo)購
             if(CollectionUtils.isEmpty(members)) return ;//校驗(yàn)會(huì)員
             employee.addMembers(members);//業(yè)務(wù)邏輯處理,為導(dǎo)購添加會(huì)員
             empDao.updateEmployee(employee);//持久化到數(shù)據(jù)庫
      }

      /**
       * 根據(jù)導(dǎo)購ID獲取導(dǎo)購對象
       * @param employeeId
       * @return
       */
      public Employee getById(Integer employeeId) {
             Objects.requireNonNull(employeeId,"導(dǎo)購ID[employeeId]不能為空");
             Employee employee = empDao.selectById(employeeId);
             if(null == employee)
                   throw new IllegalStateException(String.format("不存在導(dǎo)購[%s]", employeeId));
             return employee;
      }

      @Resource
      private EmployeeDAO empDao;
}
package com.csosm.layout.action;
import java.util.Collection;
import java.util.Collections;
import javax.annotation.Resource;
import org.apache.commons.collections.CollectionUtils;
import com.csosm.layout.dao.MemberDAO;
import com.csosm.layout.entity.Member;
/**
 * 獨(dú)屬于Member對象的應(yīng)用層
 * @author bear
 *
 */
public class MemberAction {

      /**
       * 根據(jù)會(huì)員ID獲取會(huì)員對象
       * @param memberIds
       * @return
       */
      public Collection<Member> getByIds(Collection<Integer> memberIds){
             if(CollectionUtils.isEmpty(memberIds)) return Collections.EMPTY_LIST;//如果會(huì)員ID為空則返回空列表
             return memberDao.selectByIds(memberIds);
      }

      @Resource
      private MemberDAO memberDao;
}
* Entity層【領(lǐng)域?qū)印浚核械臉I(yè)務(wù)操作集中在Entity層。
 作用:
 1、進(jìn)行業(yè)務(wù)邏輯的處理
代碼:
package com.csosm.layout.entity;
import java.util.Collection;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;
import org.apache.commons.collections.CollectionUtils;
import com.google.common.collect.Lists;
public class Employee {

      //導(dǎo)購ID
      private final Integer id;
      //導(dǎo)購名稱
      private String name;
      //導(dǎo)購門店
      private Integer storeId;
      //導(dǎo)購手上的會(huì)員 ,初始化為空
      private List<Integer> memberIds = Lists.newArrayList();

      public Employee(Integer id, String name, Integer storeId) {
             super();
             this.id = id;
             this.name = name;
             this.storeId = storeId;
      }
      /**
       * 添加單個(gè)會(huì)員
       * @param member
       */
      public void addMember(Member member) {
             Objects.requireNonNull(member,"入?yún)ember不能為空");//檢驗(yàn)會(huì)員
             this.memberIds.add(member.getId());
      }
      /**
       * 為導(dǎo)購添加多個(gè)會(huì)員
       * @param members
       */
      public void addMembers(Collection<Member> members) {
             if(CollectionUtils.isEmpty(members)) return ;//如果沒有傳入會(huì)員則返回
             this.memberIds.addAll(members.stream().map(x -> x.getId()).collect(Collectors.toSet()));
      }

      public String getName() {
             return name;
      }
      public void setName(String name) {
             this.name = name;
      }
      public Integer getStoreId() {
             return storeId;
      }
      public void setStoreId(Integer storeId) {
             this.storeId = storeId;
      }
      public List<Integer> getMemberIds() {
             return memberIds;
      }
      public Integer getId() {
             return id;
      }
    //toString、equals、hasCode 方法就不寫了
}
package com.csosm.layout.entity;
public class Member {

      //會(huì)員ID
      private final Integer id;
      //會(huì)員 名稱
      private String name;
      //會(huì)員電話
      private String phone;
      //會(huì)員性別
      private int sex;

      public Member(Integer id, String name, String phone, int sex) {
             super();
             this.id = id;
             this.name = name;
             this.phone = phone;
             this.sex = sex;
      }
      public String getName() {
             return name;
      }
      public void setName(String name) {
             this.name = name;
      }
      public String getPhone() {
             return phone;
      }
      public void setPhone(String phone) {
             this.phone = phone;
      }
      public int getSex() {
             return sex;
      }
      public void setSex(int sex) {
             this.sex = sex;
      }
      public Integer getId() {
             return id;
      }

}
* dao層【基礎(chǔ)設(shè)施層】:實(shí)現(xiàn)將對象持久化到數(shù)據(jù)庫
代碼:
package com.csosm.layout.dao;
import com.csosm.layout.entity.Employee;
/**
 * 獨(dú)屬于Employee的持久化層
 * @author bear
 *
 */
//以下操作可采取MYbatis的方式,也可以采取spring自帶的jdbcTemplate的方式就行對象持久化并與數(shù)據(jù)進(jìn)行交互
public class EmployeeDAO {

      /**
       * 更新導(dǎo)購對象到數(shù)據(jù)庫
       * @param employee 導(dǎo)購
       */
      public void updateEmployee(Employee employee) {
             //TODO 實(shí)現(xiàn)對象持久化
      }

      /**
       * 根據(jù)導(dǎo)購ID從數(shù)據(jù)庫中提取導(dǎo)購對象
       * @param id 導(dǎo)購ID
       * @return
       */
      public Employee selectById(Integer id) {
             //TODO 從數(shù)據(jù)庫中獲取導(dǎo)購對象
             return null;
      }

}

package com.csosm.layout.dao;
import java.util.Collection;
import com.csosm.layout.entity.Member;
/**
 * 獨(dú)屬于Member的持久化層
 * @author bear
 *
 */
//以下操作可采取MYbatis的方式,也可以采取spring自帶的jdbcTemplate的方式就行對象持久化并與數(shù)據(jù)進(jìn)行交互
public class MemberDAO {

      /**
       * 根據(jù)多個(gè)會(huì)員ID從數(shù)據(jù)庫獲取多個(gè)會(huì)員
       * @param memberIds 會(huì)員ID集合
       * @return
       */
      public Collection<Member> selectByIds(Collection<Integer> memberIds){
             //TODO 從數(shù)據(jù)庫提取會(huì)員信息
             return null;
      }
}
向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI