1. 程式人生 > >淺談java領域模式分層實現

淺談java領域模式分層實現

門戶 開發技術 多個 esp 判斷 單個 jdbc 維護 mark

隨著軟件開發技術不停地叠代更新,現在的系統基本上實現了由表示、邏輯一體化到分層模式的轉變。 一個好的層次劃分不僅僅可以使代碼結構更加清晰、增添代碼可讀性。同時也使得項目分工更加明確,維護更為便利。 而我要介紹的是在java開發領域中,面向對象的分層模式-領域模型分層。 領域模型分層最主要的工作就是分離領域,分離領域就是將領域對象與系統中的其他功能分離,從而避免將領域概念和其他只與軟件技術相關的的概念相混淆,其最終目的是為了讓對象更專註於邏輯處理而無需關註其他的事物。 領域模型設計書籍曾描述過領域模型可分為4層,分別是 1、用戶界面層 負責向用戶顯示信息和解釋用戶指令 2、應用層 定義軟件要完成的任務,並指揮表達領域概念的對象來解決問題 3、領域層(模型層) 負責表達業務概念,業務狀態信息以及業務規則 4、基礎設施層 為各層提供通用的技術能力,為應用層傳遞消息,為領域層提供持久化機制。 在結合實際的開發經驗與書本的知識,認為在開發過程中可落地成如下幾層: Controller層【用戶界面層】、Service層【應用層】、Action層【應用層】、entity層【領域層】、DAO層【基礎設施層】。 其層與層的關系如下圖: ![](https://s1.51cto.com/images/blog/201903/27/e8e69af0cb209e0602b8bb01dbd56bea.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=) 為了更好的理解上述分層架構,舉個栗子來說明一下。 先設定一個場景: 有一家服裝店,店裏有店長和多個導購。該店有一批會員,為了更好的服務會員,店長需要將會員分配給導購,讓導購服務自身的會員。 待實現功能:給導購分配會員 ![](https://s1.51cto.com/images/blog/201903/27/fb28b46d4e690f950add6c2c1614778f.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=) * Controller層【用戶界面層】:負責與界面或其他系統的對接,相當於一個系統的門戶。所有其他非本系統的用戶都應該先將請求提交給Cotroller層。 作用: 1、負責接待外來用戶,並將請求傳遞給下一層 2、校驗請求的合法性【如:判斷用戶合法性,請求參數合理性】 3、相應用戶請求【系統將請求處理完畢後,將返回的結果組合成用戶想要的結果】
代碼:
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;
/**
 * 用戶界面層,為前端或其他系統用戶提供訪問接口
 * @author bear
 *
 */
@RequestMapping("/employee")
public class EmployeeController {

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

       @Resource
       private EmployeeService employeeService;

}`
Service層【應用層】:對接Controller層,為Controller層的每一個請求提供對應的接口,為下一層Action層做數據準
作用:
1、將controller傳遞的數據還原成對象
2、進行跨對象邏輯處理
代碼:
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的應用層,可跨對象操作
 * @author bear
 *
 */
public class EmployeeService {

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

      @Resource
      private EmployeeAction employeeAction;
      @Resource
      private MemberAction memberAction;
}
* Action層【應用層】:該層只對Entity層負責,是Entity層對外提供的接口
作用:
1、為系統內部提供操作實體的接口
2、調用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;
/**
 * 獨屬於Employee對象的應用層
 * 盡量使用對象
 * @author bear
 *
 */
public class EmployeeAction {
      /**
       * 給導購添加多個會員
       * @param employee 導購
       * @param members 多個會員
       */
      public void addMembers(Employee employee,Collection<Member> members) {
             Objects.requireNonNull(employee,"導購[employee]不能為空");//校驗導購
             if(CollectionUtils.isEmpty(members)) return ;//校驗會員
             employee.addMembers(members);//業務邏輯處理,為導購添加會員
             empDao.updateEmployee(employee);//持久化到數據庫
      }

      /**
       * 根據導購ID獲取導購對象
       * @param employeeId
       * @return
       */
      public Employee getById(Integer employeeId) {
             Objects.requireNonNull(employeeId,"導購ID[employeeId]不能為空");
             Employee employee = empDao.selectById(employeeId);
             if(null == employee)
                   throw new IllegalStateException(String.format("不存在導購[%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;
/**
 * 獨屬於Member對象的應用層
 * @author bear
 *
 */
public class MemberAction {

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

      @Resource
      private MemberDAO memberDao;
}
* Entity層【領域層】:所有的業務操作集中在Entity層。
 作用:
 1、進行業務邏輯的處理
代碼:
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 {

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

      public Employee(Integer id, String name, Integer storeId) {
             super();
             this.id = id;
             this.name = name;
             this.storeId = storeId;
      }
      /**
       * 添加單個會員
       * @param member
       */
      public void addMember(Member member) {
             Objects.requireNonNull(member,"入參member不能為空");//檢驗會員
             this.memberIds.add(member.getId());
      }
      /**
       * 為導購添加多個會員
       * @param members
       */
      public void addMembers(Collection<Member> members) {
             if(CollectionUtils.isEmpty(members)) return ;//如果沒有傳入會員則返回
             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 {

      //會員ID
      private final Integer id;
      //會員 名稱
      private String name;
      //會員電話
      private String phone;
      //會員性別
      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層【基礎設施層】:實現將對象持久化到數據庫
代碼:
package com.csosm.layout.dao;
import com.csosm.layout.entity.Employee;
/**
 * 獨屬於Employee的持久化層
 * @author bear
 *
 */
//以下操作可采取MYbatis的方式,也可以采取spring自帶的jdbcTemplate的方式就行對象持久化並與數據進行交互
public class EmployeeDAO {

      /**
       * 更新導購對象到數據庫
       * @param employee 導購
       */
      public void updateEmployee(Employee employee) {
             //TODO 實現對象持久化
      }

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

}

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

      /**
       * 根據多個會員ID從數據庫獲取多個會員
       * @param memberIds 會員ID集合
       * @return
       */
      public Collection<Member> selectByIds(Collection<Integer> memberIds){
             //TODO 從數據庫提取會員信息
             return null;
      }
}

淺談java領域模式分層實現