浅谈java领域模式分层实现
随着软件开发技术不停地迭代更新,现在的系统基本上实现了由表示、逻辑一体化到分层模式的转变。
一个好的层次划分不仅仅可以使代码结构更加清晰、增添代码可读性。同时也使得项目分工更加明确,维护更为便利。
而我要介绍的是在java开发领域中,面向对象的分层模式-领域模型分层。
领域模型分层最主要的工作就是分离领域,分离领域就是将领域对象与系统中的其他功能分离,从而避免将领域概念和其他只与软件技术相关的的概念相混淆,其最终目的是为了让对象更专注于逻辑处理而无需关注其他的事物。
领域模型设计书籍曾描述过领域模型可分为4层,分别是
1、用户界面层
负责向用户显示信息和解释用户指令
2、应用层
定义软件要完成的任务,并指挥表达领域概念的对象来解决问题
3、领域层(模型层)
负责表达业务概念,业务状态信息以及业务规则
4、基础设施层
为各层提供通用的技术能力,为应用层传递消息,为领域层提供持久化机制。
在结合实际的开发经验与书本的知识,认为在开发过程中可落地成如下几层:
Controller层【用户界面层】、Service层【应用层】、Action层【应用层】、entity层【领域层】、DAO层【基础设施层】。
其层与层的关系如下图:
为了更好的理解上述分层架构,举个栗子来说明一下。
先设定一个场景:
有一家服装店,店里有店长和多个导购。该店有一批会员,为了更好的服务会员,店长需要将会员分配给导购,让导购服务自身的会员。
待实现功能:给导购分配会员
作用:
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; }}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。