javascript
Spring–设计领域模型和服务层
讓我們稍微回顧一下這些要點(diǎn),然后嘗試將這種簡(jiǎn)單的人類語(yǔ)言轉(zhuǎn)換為程序員可以發(fā)現(xiàn)的某些關(guān)系和實(shí)體。
- 實(shí)體:經(jīng)理,員工,時(shí)間表,任務(wù)
好的,我們現(xiàn)在應(yīng)該對(duì)領(lǐng)域有了更好的了解,所以讓我們創(chuàng)建maven項(xiàng)目并實(shí)現(xiàn)類。 使用Maven,您將獲得漂亮而干凈的項(xiàng)目結(jié)構(gòu)。 您所需要做的就是安裝Maven,并在項(xiàng)目中包含pom.xml。 您可以“手動(dòng)”執(zhí)行此操作,并通過(guò)終端構(gòu)建應(yīng)用程序(在這種情況下,只需創(chuàng)建常規(guī)項(xiàng)目并添加pom.xml文件)。 我更喜歡使用一些其他工具。 IntelliJ IDEA,NetBeans和Springsource Tool Suite具有現(xiàn)成的Maven支持。 如果您使用的是純Eclipse,請(qǐng)檢查m2eclipse插件。
無(wú)論哪種方式,這都是我們項(xiàng)目的一些基本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>現(xiàn)在讓我們實(shí)現(xiàn)領(lǐng)域模型。 創(chuàng)建包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+ ']';}} 如您所見(jiàn),Manager和Employee類沒(méi)有很多屬性,它們?cè)谶@里只是為了擁有類型安全模型。 在“現(xiàn)實(shí)世界”中,他們可能還有其他各種屬性,例如姓,生日,地址等等,甚至可能是普通的父類。
而且,我們現(xiàn)在并不真正在乎各種約束。 例如,我們只能在任務(wù)上填寫整數(shù)小時(shí),依此類推。
現(xiàn)在是時(shí)候定義我們的服務(wù)層–定義業(yè)務(wù)操作并為這些操作建立接口。 因此,讓我們制作軟件包org.timesheet.service 。 首先,我們將創(chuàng)建GenericDao接口,在其中我們將為系統(tǒng)中的每個(gè)實(shí)體定義基本的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();}現(xiàn)在,讓我們不必?fù)?dān)心實(shí)際的持久層-讓我們創(chuàng)建一些虛擬實(shí)現(xiàn)并將所有數(shù)據(jù)存儲(chǔ)在內(nèi)存中。 我們將其放入新包– org.timesheet.service.impl中 。 不用擔(dān)心,稍后我們將使用Hibernate。 這是虛擬實(shí)現(xiàn)的代碼:
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;}}接下來(lái),我們將編寫我們的第一個(gè)簡(jiǎn)單測(cè)試。 現(xiàn)在,我們將第一個(gè)依賴項(xiàng)添加到pom.xml文件的JUnit庫(kù)中。 因?yàn)樗堑谝粋€(gè),所以我們還需要將其包裝到dependencies元素中,如下所示:
<dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.10</version></dependency></dependencies>這是我們針對(duì)Employee DAO的第一個(gè)非常簡(jiǎn)單的單元測(cè)試。 我們現(xiàn)在不做其他任何事情,因?yàn)槲覀冞€沒(méi)有真正要測(cè)試的東西。 但是,更重要的是,我們?nèi)绾?strong>依賴測(cè)試中DAO的實(shí)現(xiàn)(我們使用新的InMemoryDao… )。 這很不好,因?yàn)槲覀儜?yīng)該只測(cè)試定義接口的公共API。 在本教程的后面,您將看到Spring如何幫助我們解決此類問(wèn)題。
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的其余測(cè)試編寫單元測(cè)試。 但是由于我們現(xiàn)在沒(méi)有合適的實(shí)現(xiàn)來(lái)測(cè)試,因此我們稍后將一起進(jìn)行測(cè)試。
事情并非總是那么容易。 這不僅與CRUD操作有關(guān),還與業(yè)務(wù)操作不夠通用,無(wú)法用簡(jiǎn)單的DAO表示出來(lái)。 因此,讓我們定義一些業(yè)務(wù)操作并為其創(chuàng)建單獨(dú)的服務(wù)。 我們將其稱為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);}好的,到目前為止很好。 您現(xiàn)在已經(jīng)知道在下一個(gè)示例中我們將使用什么業(yè)務(wù)領(lǐng)域。 您可能現(xiàn)在想知道-我們還沒(méi)有使用Spring,為什么呢? 請(qǐng)記住, Spring的最初目的是簡(jiǎn)化企業(yè)Java開(kāi)發(fā)并鼓勵(lì)POJO開(kāi)發(fā)模型。 因此,將Spring與該基本模型一起使用將非常容易,因此我們不會(huì)將核心邏輯與不必要的依賴項(xiàng)混合在一起。
在下面的圖片中,到目前為止,我們已經(jīng)構(gòu)建了項(xiàng)目的結(jié)構(gòu),因此請(qǐng)確保您表現(xiàn)良好。
參考: 第1部分–在vrtoonjava博客上,由我們的JCG合作伙伴 Michal Vrtiak 設(shè)計(jì)域模型和服務(wù)層 。
翻譯自: https://www.javacodegeeks.com/2012/09/spring-designing-domain-model-and.html
總結(jié)
以上是生活随笔為你收集整理的Spring–设计领域模型和服务层的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 苹果手机可以下载安卓模拟器吗(安卓模拟器
- 下一篇: 安卓平板杀毒软件哪个好用(安卓平板杀毒软