Spring–设计领域模型和服务层

我们将为时间表管理构建应用程序。 因此,让我们首先考虑一些用例和实体。 让我用几个项目符号写它们:
  1. 任务由经理分配给员工。 一项任务可以分配给许多员工。
  2. 员工将他在某些任务上工作的小时数填满至系统。
  3. 经理/员工查看时间表上的报告(时间表可以更改)。

让我们稍微回顾一下这些要点,然后尝试将这种简单的人类语言转换为程序员可以发现的某些关系和实体。

  • 实体:经理,员工,时间表,任务

好的,我们现在应该对领域有了更好的了解,所以让我们创建maven项目并实现类。 使用Maven,您将获得漂亮而干净的项目结构。 您所需要做的就是安装Maven,并在项目中包含pom.xml。 您可以“手动”执行此操作,并通过终端构建应用程序(在这种情况下,只需创建常规项目并添加pom.xml文件)。 我更喜欢使用一些其他工具。 IntelliJ IDEA,NetBeans和Springsource Tool Suite具有现成的Maven支持。 如果您使用的是纯Eclipse,请检查m2eclipse插件。

无论哪种方式,这都是我们项目的一些基本Maven配置:

<project xmlns='http://maven.apache.org/POM/4.0.0' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd'><modelVersion>4.0.0</modelVersion><groupId>org.timesheet</groupId><artifactId>org.timesheet</artifactId><version>0.0.1-SNAPSHOT</version><name>Timesheet Management On Spring</name><build><plugins><plugin><groupId>org.apache.maven.plugins</groupId><artifactId>maven-compiler-plugin</artifactId><configuration><source>1.6</source><target>1.6</target></configuration></plugin></plugins></build>
</project>

现在让我们实现领域模型。 创建包org.timesheet.domain并定义以下类。

package org.timesheet.domain;public class Employee {private String name;private String department;public Employee(String name, String department) {this.name = name;this.department = department;}public String getName() {return name;}public String getDepartment() {return department;}
}
package org.timesheet.domain;public class Manager {private String name;public Manager(String name) {this.name = name;}public String getName() {return name;}
}
package org.timesheet.domain;import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;public class Task {private List<Employee> assignedEmployees = new ArrayList<Employee>();private Manager manager;private boolean completed;private String description;public Task(String description, Manager manager, Employee... employees) {this.description = description;this.manager = manager;assignedEmployees.addAll(Arrays.asList(employees));completed = false;}public Manager getManager() {return manager;}public List<Employee> getAssignedEmployees() {return assignedEmployees;}public void addEmployee(Employee e) {assignedEmployees.add(e);}public void removeEmployee(Employee e) {assignedEmployees.remove(e);}public void completeTask() {completed = true;}
}
package org.timesheet.domain;public class Timesheet {private Employee who;private Task task;private Integer hours;public Timesheet(Employee who, Task task, Integer hours) {this.who = who;this.task = task;this.hours = hours;}public Employee getWho() {return who;}public Task getTask() {return task;}public Integer getHours() {return hours;}/*** Manager can alter hours before closing task* @param hours New amount of hours*/public void alterHours(Integer hours) {this.hours = hours;}@Overridepublic String toString() {return 'Timesheet [who=' + who + ', task=' + task + ', hours=' + hours+ ']';}}

如您所见,Manager和Employee类没有很多属性,它们在这里只是为了拥有类型安全模型。 在“现实世界”中,他们可能还有其他各种属性,例如姓,生日,地址等等,甚至可能是普通的父类。
而且,我们现在并不真正在乎各种约束。 例如,我们只能在任务上填写整数小时,依此类推。

现在是时候定义我们的服务层–定义业务操作并为这些操作建立接口。 因此,让我们制作软件包org.timesheet.service 。 首先,我们将创建GenericDao接口,在其中我们将为系统中的每个实体定义基本的CRUD操作。

package org.timesheet.service;import java.util.List;public interface GenericDao<E, K> {void add(E entity);void update(E entity);void remove(E entity);E find(K key);List<E> list();}

现在,让我们不必担心实际的持久层-让我们创建一些虚拟实现并将所有数据存储在内存中。 我们将其放入新包– org.timesheet.service.impl中 。 不用担心,稍后我们将使用Hibernate。 这是虚拟实现的代码:

package org.timesheet.service.impl;import java.util.ArrayList;
import java.util.List;import org.timesheet.service.GenericDao;public class InMemoryDao<E, K> implements GenericDao<E, K> {private List<E> entities = new ArrayList<E>();@Overridepublic void add(E entity) {entities.add(entity);}@Overridepublic void update(E entity) {throw new UnsupportedOperationException('Not supported in dummy in-memory impl!');}@Overridepublic void remove(E entity) {entities.remove(entity);}@Overridepublic E find(K key) {if (entities.isEmpty()) {return null;}// just return the first one sice we are not using any keys ATMreturn entities.get(0);}@Overridepublic List<E> list() {return entities;}}

接下来,我们将编写我们的第一个简单测试。 现在,我们将第一个依赖项添加到pom.xml文件的JUnit库中。 因为它是第一个,所以我们还需要将其包装到dependencies元素中,如下所示:

<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.10</version></dependency></dependencies>

这是我们针对Employee DAO的第一个非常简单的单元测试。 我们现在不做其他任何事情,因为我们还没有真正要测试的东西。 但是,更重要的是,我们如何依赖测试中DAO的实现(我们使用新的InMemoryDao… )。 这很不好,因为我们应该只测试定义接口的公共API。 在本教程的后面,您将看到Spring如何帮助我们解决此类问题。

package org.timesheet.service;import static org.junit.Assert.*;import java.util.List;import org.junit.Before;
import org.junit.Test;
import org.timesheet.domain.Employee;
import org.timesheet.service.impl.InMemoryDao;public class EmployeeDaoTest {private GenericDao<Employee, Long> employeeDao = new InMemoryDao<Employee, Long>();@Beforepublic void setUp() {for (int i = 0; i < 5; i++) {Employee e = new Employee('Mike ' + i, 'IT');employeeDao.add(e);}}@Testpublic void testAdd() {int oldSize = employeeDao.list().size();Employee e = new Employee('Bob', 'IT');employeeDao.add(e);int newSize = employeeDao.list().size();assertFalse (oldSize == newSize);}@Testpublic void testRemove() {int oldSize = employeeDao.list().size();Employee e = employeeDao.find(1L);employeeDao.remove(e);int newSize = employeeDao.list().size();assertFalse (oldSize == newSize);}@Testpublic void testUpdate() {//TODO: need real implementation}@Testpublic void testList() {List<Employee> list = employeeDao.list();assertNotNull (list);assertFalse (list.isEmpty());}}

如果需要,还可以为其他DAO的其余测试编写单元测试。 但是由于我们现在没有合适的实现来测试,因此我们稍后将一起进行测试。

事情并非总是那么容易。 这不仅与CRUD操作有关,还与业务操作不够通用,无法用简单的DAO表示出来。 因此,让我们定义一些业务操作并为其创建单独的服务。 我们将其称为TimesheetService。

package org.timesheet.service;import org.timesheet.domain.Employee;
import org.timesheet.domain.Manager;
import org.timesheet.domain.Task;import java.util.List;/*** Business that defines operations on timesheets*/
public interface TimesheetService {/*** @return Finds the busiest task (with the most of employees).* Returns {@code null} when tasks are empty.*/Task busiestTask();/*** Finds all the tasks for the employee.* @param e Employee* @return Tasks*/List<Task> tasksForEmployee(Employee e);/*** Finds all the tasks for the manager.* @param m Manager* @return Tasks*/List<Task> tasksForManager(Manager m);}

好的,到目前为止很好。 您现在已经知道在下一个示例中我们将使用什么业务领域。 您可能现在想知道-我们还没有使用Spring,为什么呢? 请记住, Spring的最初目的是简化企业Java开发并鼓励POJO开发模型。 因此,将Spring与该基本模型一起使用将非常容易,因此我们不会将核心逻辑与不必要的依赖项混合在一起。

在下面的图片中,到目前为止,我们已经构建了项目的结构,因此请确保您表现良好。

参考: 第1部分–在vrtoonjava博客上,由我们的JCG合作伙伴 Michal Vrtiak 设计域模型和服务层 。


翻译自: https://www.javacodegeeks.com/2012/09/spring-designing-domain-model-and.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/371403.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

如何把很多照片拼成一张照片_一张现场照片引发的中韩之争

来源&#xff1a;渤海新水手聊船专栏前几天&#xff0c;微信群里(造船质量技术高级交流群)一位网友发了一张韩国船厂的现场照片&#xff0c;没想到瞬间引发全群几十位网友的热烈讨论&#xff0c;中韩之争就此上演&#xff01;照片反映出的是国内船厂很难做到的部分——分段预装…

计算机文档设置,电脑这样设置快速的共享文件、分享文档!

原标题&#xff1a;电脑这样设置快速的共享文件、分享文档&#xff01;在日常办公的时候&#xff0c;有时需要共同使用一些文件或者文档或者一些视频资料。那么要怎么方便的使用这些共同的资源呢&#xff1f;当然这时大家可能会说可以用QQ、微信传给对方不就可以了。但是如果文…

关于vue 框架与后台框架的混合使用的尝试

这几天我在研究前台框架和后台框架融合的问题,进行了一些尝试; 我前台选择的是 vue,当然也可以选择 react 等其他 mvvm 框架,不过 vue 对于我来说是最熟悉的; 后台话,我选择的是 php 的 lumen 框架,他是laravel 的简化版,因为比较轻量,所以这也是我的选择; 先说下我这边的环境:…

服务器 raid 1t硬盘吗,用了4块1T的硬盘,做了raid5,显示有2.7T,但是分区做完系统后,有700多G不能动...

满意答案ouourpt892013.11.14采纳率&#xff1a;46% 等级&#xff1a;12已帮助&#xff1a;13583人出现这种情况是由于创建的硬盘使用的是基本磁盘(MBR)格式&#xff0c;因受MBR磁盘格式技术的限制&#xff0c;MBR磁盘只支持2TB的磁盘容量&#xff0c;所以出现了你所说的情况…

vi编辑器服务器维护,vi编辑器有哪几种工作模式及如何转换_网站服务器运行维护,vi编辑器,工作模式...

整理分享一些 Linux思维导图(值得收藏)_网站服务器运行维护本篇文章整理分享了一些 Linux思维导图(值得收藏)。有一定的参考价值&#xff0c;有需要的朋友可以参考一下&#xff0c;希望对大家有所帮助。vi编辑器有三种基本的工作模式&#xff0c;分别是&#xff1a;指令行模式、…

(八)cmockery中的calculator和run_tests函数的注释代码

所分析的calculator.c和calculator_test.c文件位于 工程中的 cmockery/src/example/ 目录下&#xff0c;是一个相对而言比较全面的样例程序&#xff0c;用到了cmockery项目中的大多数单元测试方法。基本上涵盖了之前所有的样例程序中的用法&#xff0c;还有两组测试是database操…

第一章魔兽窗口

开始显示第一个窗体 用户直接点登陆的话就会提示用户名不能为空密码不能为空 没有账号的话只能先注册&#xff0c;点击蓝色摁钮进入下一个窗体 这里有判断是否为空&#xff0c;注册成功后利用窗体传值&#xff0c;并且打开第一个窗口 把注册的用户名和密码写上去就可以的登陆到…

Apache Digester示例–轻松配置

解决问题–硬编码&#xff0c;需要为您的应用程序创建自定义配置&#xff0c;例如struts配置文件&#xff0c;以仅通过更改文件来改变应用程序行为。 Apache Digester可以轻松为您完成此任务。 使用Apache Digester相当容易将XML文档转换为相应的Java bean对象层次结构。 请参阅…

Java FlameGraph 火焰图

上周一个偶然的机会听同事提到了Java FlameGraph&#xff0c;刚实验了一下&#xff0c;效果非常好。 一、什么是FlameGraph 直接看图说话。FlameGraph 是 SVG格式&#xff0c;矢量图&#xff0c;可以随意扩大缩小&#xff0c;看不清的信息可以放大看。图中&#xff0c;各种红橙…

烟草局计算机笔试,2020年广西南宁烟草局什么时候笔试?

最近广西烟草局各地市社招通知频发&#xff0c;南宁烟草局报名截止至今都无任何消息&#xff0c;根据往年的考情&#xff0c;通知近期很大可能会发布&#xff0c;将于6月底完成笔面!你备考好了吗&#xff1f;今天广西中公国企小编来给大家说一下南宁烟草局社招的笔试内容及备考…

JAVA Swing 组件演示***

下面是Swing组件的演示&#xff1a; package a_swing;import java.awt.BorderLayout; import java.awt.Color; import java.awt.Container; import java.awt.Cursor; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.…

centos 获取硬件序列号_如何在 Linux 上查找硬件规格

在 Linux 系统上有许多工具可用于查找硬件规格。-- Sk&#xff08;作者&#xff09;在 Linux 系统上有许多工具可用于查找硬件规格。在这里&#xff0c;我列出了四种最常用的工具&#xff0c;可以获取 Linux 系统的几乎所有硬件&#xff08;和软件&#xff09;细节。好在是这些…

Spring –持久层–编写实体并配置Hibernate

欢迎来到本教程的第二部分。 当您看到本文有多长时间时&#xff0c;请不要惊慌–我向您保证&#xff0c;这主要是简单的POJO和一些生成的代码。 在开始之前&#xff0c;我们需要更新我们的Maven依赖项&#xff0c;因为我们现在将使用Hibernate和Spring。 将以下依赖项添加到pom…

无线服务器主机名是,wifi默认服务器主机名

wifi默认服务器主机名 内容精选换一换以CentOS 7操作系统的弹性云服务器为例&#xff1a;登录Linux弹性云服务器&#xff0c;查看“cloud-init”的配置文件。检查“/etc/cloud/cloud.cfg”文件中“update_hostname”是否被注释或者删除。如果没有被注释或者删除&#xff0c;则需…

pygame里面物体闪烁运动_利用自闪烁发光二极管探究小车在倾斜轨道上的运动规律...

2020年11月23日&#xff0c;周一&#xff0c;24小时安全值班。利用当班中午的时间&#xff0c;微主在创客空间测试了自闪烁发光二极管在匀加速运动中的效果&#xff0c;结果还比较满意。将小车放置在倾斜的轨道上&#xff0c;将自闪烁发光二极管和纽扣电池构成频闪光源&#xf…

python网络爬虫与信息提取 学习笔记day3

Day3&#xff1a; 只需两行代码解析html或xml信息 具体代码实现:day3_1 注意BeautifulSoup的B和S需要大写&#xff0c;因为python大小写敏感 import requests r requests.get("http://python123.io/ws/demo.html") r.text demo r.text from bs4 import Beauti…

王者荣耀微信哪个服务器人最少,王者荣耀:微信区王者人数锐减,大神们都去哪了?这些原因很真实...

原标题&#xff1a;王者荣耀&#xff1a;微信区王者人数锐减&#xff0c;大神们都去哪了&#xff1f;这些原因很真实王者荣耀&#xff1a;微信区王者人数锐减&#xff0c;大神们都去哪了&#xff1f;这些原因很真实大家好&#xff01;王者荣耀S16赛季已经开启一月之余&#xff…

一个div压在另一个div上面_【CSS小分享】用CSS画一个新拟态风格键盘

什么是新拟态新拟态的英文名称是“Neumorphism”&#xff0c;也有人称为“Soft UI”。简单讲&#xff0c;新拟态是一种图形样式&#xff0c;其原理是通过模拟真实物体来为界面的UI元素赋予真实感。新拟态风格起源于dribbble&#xff0c;后面陆续被收录在2020设计趋势预测里面&a…

Hibernate中Hql查询

这篇随笔将会记录hql的常用的查询语句&#xff0c;为日后查看提供便利。 在这里通过定义了三个类&#xff0c;Special、Classroom、Student来做测试&#xff0c;Special与Classroom是一对多&#xff0c;Classroom与Student是一对多的关系&#xff0c;这里仅仅贴出这三个bean的属…

Java代码质量工具–概述

最近&#xff0c;我有机会在本地IT社区聚会上介绍了该主题。 这是基本演示&#xff1a; Java代码质量工具 以及更有意义的思维导图&#xff1a; 但是&#xff0c;我认为我需要更深入地探讨这一主题。 这篇博客文章应该像是在此方向上进行进一步调查的起点。 1. CodePro Anal…