浅谈java领域模式分层实现

随着软件开发技术不停地迭代更新,现在的系统基本上实现了由表示、逻辑一体化到分层模式的转变。
一个好的层次划分不仅仅可以使代码结构更加清晰、增添代码可读性。同时也使得项目分工更加明确,维护更为便利。
而我要介绍的是在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;
      }
}

原文地址:https://blog.51cto.com/14207809/2370215

时间: 2024-08-27 07:58:55

浅谈java领域模式分层实现的相关文章

浅谈java类集框架和数据结构(2)

继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主要有最重要的三种实现:ArrayList,Vector,LinkedList,三种List均来自AbstracList的实现,而AbstracList直接实现了List接口,并拓展自AbstractCollection. 在三种实现中,ArrayList和Vector使用了数组实现,可以认为这两个是

!! 浅谈Java学习方法和后期面试技巧

浅谈Java学习方法和后期面试技巧 昨天查看3303回复33 部落用户大酋长 下面简单列举一下大家学习java的一个系统知识点的一些介绍 一.java基础部分:java基础的时候,有些知识点是非常重要的,比如循环系列.For,while,do-while.这方面只要大家用心点基本没什么难点. 二.面向对象:oop面向对象的时候,偏重理论,相信这方面的文章也很多,大家可以多看看,在这就不说了.重点掌握面向对象的三大特征和基本原理. 三.java核心一:这方面主要偏重API,所以在学习了这章的时候,

浅谈-Java设计模式之动态代理

动态代理模式(Dynamic Proxy Pattern): 在java的动态代理机制中,有两个重要的类或接口,一个是 InvocationHandler(Interface).另一个则是 Proxy(Class),这一个类和接口是实现我们动态代理所必须用到的. 首先我们先来看看java的API帮助文档是怎么样对这两个类进行描述的: InvocationHandler该接口唯一方法 invoke(Object proxy, Method method, Object[] args) Object

浅谈 Java Printing

浅谈 Java  Printing 其实怎么说呢?在写这篇博文之前,我对java printing 可以说是一无所知的.以至于我在敲文字时, 基本上是看着api文档翻译过来的.这虽然看起来非常的吃力,但是我相信,有道大哥不会辜负我的.嘻 嘻! Java Printing 技术,也就是我们平时所接触的打印,只不过是说可以用Java实现而已. 一.Java Printing 打印简介 Java Printing API能够使java应用程序实现相关的打印功能,如: 1.打印所有 Java 2D 和

【转】浅谈Java中的equals和==

浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str2 = new String("hello"); 3 4 System.out.println(str1==str2); 5 System.out.println(str1.equals(str2)); 为什么第4行和第5行的输出结果不一样?==和equals方法之间的区别是什么?如果在初

浅谈java异常[Exception]

本文转自:focusJ 一. 异常的定义 在<java编程思想>中这样定义 异常:阻止当前方法或作用域继续执行的问题.虽然java中有异常处理机制,但是要明确一点,决不应该用"正常"的态度来看待异常.绝对一点说异常就是某种意义上的错误,就是问题,它可能会导致程序失败.之所以java要提出异常处理机制,就是要告诉开发人员,你的程序出现了不正常的情况,请注意. 记得当初学习java的时候,异常总是搞不太清楚,不知道这个异常是什么意思,为什么会有这个机制?但是随着知识的积累逐渐也

浅谈Java虚拟机

最近发现MDT推出去的系统的有不同问题,其问题就不说了,主要是策略权限被域继承了.比如我们手动安装的很多东东都是未配置壮态,推的就默认为安全壮态了,今天细找了一下,原来把这个关了就可以了. 浅谈Java虚拟机,布布扣,bubuko.com

浅谈Java中的对象和引用

浅谈Java中的对象和对象引用 在Java中,有一组名词经常一起出现,它们就是"对象和对象引用",很多朋友在初学Java的时候可能经常会混淆这2个概念,觉得它们是一回事,事实上则不然.今天我们就来一起了解一下对象和对象引用之间的区别和联系. 1.何谓对象? 在Java中有一句比较流行的话,叫做"万物皆对象",这是Java语言设计之初的理念之一.要理解什么是对象,需要跟类一起结合起来理解.下面这段话引自<Java编程思想>中的一段原话: "按照通

浅谈Java中的equals和==

浅谈Java中的equals和== 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new String("hello"); 2 String str2 = new String("hello"); 3 4 System.out.println(str1==str2); 5 System.out.println(str1.equals(str2)); 为什么第4行和第5行的输出结果不一样?==和equals方法之间的区别是什么?如果在初