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