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.pswp.cn/news/371403.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/371403.shtml
英文地址,請注明出處:http://en.pswp.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 的簡化版,因為比較輕量,所以這也是我的選擇; 先說下我這邊的環境:…

GitHub上整理的一些工具

GitHub上整理的一些工具 GitHub 2015-11-19 10:10:47 發布您的評價: 0.0 收藏 5收藏技術站點 Hacker News&#xff1a;非常棒的針對編程的鏈接聚合網站Programming reddit&#xff1a;同上MSDN&#xff1a;微軟相關的官方技術集中地&#xff0c;主要是文檔類infoq&#x…

服務器 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;所以出現了你所說的情況…

如何編寫更好的POJO服務

在Java中&#xff0c;您可以輕松地在Plain Old Java Object&#xff08;POJO&#xff09;類中實現一些業務邏輯&#xff0c;并且可以在高級服務器或框架中輕松運行它們。 有許多服務器/框架&#xff0c;例如JBossAS&#xff0c;Spring或Camel等&#xff0c;它們使您可以部署POJ…

mongo 唯一約束索引_快速掌握mongoDB(三)——mongoDB的索引詳解

1 mongoDB索引的管理本節介紹mongoDB中的索引&#xff0c;熟悉mysql/sqlserver等關系型數據庫的小伙伴應該都知道索引對優化數據查詢的重要性。我們先簡單了解一下索引&#xff1a;索引的本質就是一個排序的列表&#xff0c;在這個列表中存儲著索引的值和包含這個值的數據(數據…

HBase MapReduce

1. HBase to HBase Mapper 繼承 TableMapper&#xff0c;輸入為Rowkey和Result. public abstract class TableMapper<KEYOUT, VALUEOUT> extends Mapper<ImmutableBytesWritable, Result, KEYOUT, VALUEOUT> { public TableMapper() { }} package com.scb.ja…

第六期的知識點

1.volatile詳解 在應用程序中&#xff0c;volatile主要是被設計用來修飾被不同線程訪問和修改的變量 .volatile的本意是“易變的” 因為訪問寄存器要比訪問內存單元快的多,所以編譯器一般都會作減少存取內存的優化&#xff0c;但有可能會讀臟數據。當要求使用volatile聲明變量值…

在DelayQueue中更改延遲,從而更改順序

因此&#xff0c;我正在研究構建一個簡單的對象緩存&#xff0c;該緩存在給定時間后會使對象過期。 顯而易見的機制是使用Java并發包中的DelayedQueue類。 但我想知道是否有可能在將對象添加到隊列后更新延遲。 看一下Delayed接口&#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操…

家用雙wan口路由器推薦_請推薦雙WAN口的有線千兆硬路由器?

利益相關&#xff1a;TP-LINK一線銷售人員(來看看會不會有推薦我司產品的2333 )路由器&#xff1a;TL-ER3220G&#xff0c;帶機量300終端&#xff0c;可管理50個AP&#xff0c;最大支持四條寬帶接入POE交換機&#xff1a;TL-SF1005P(5口百兆) TL-SG1005P(5口千兆) TL-SF1009PH(…

第一章魔獸窗口

開始顯示第一個窗體 用戶直接點登陸的話就會提示用戶名不能為空密碼不能為空 沒有賬號的話只能先注冊&#xff0c;點擊藍色摁鈕進入下一個窗體 這里有判斷是否為空&#xff0c;注冊成功后利用窗體傳值&#xff0c;并且打開第一個窗口 把注冊的用戶名和密碼寫上去就可以的登陸到…

Apache Digester示例–輕松配置

解決問題–硬編碼&#xff0c;需要為您的應用程序創建自定義配置&#xff0c;例如struts配置文件&#xff0c;以僅通過更改文件來改變應用程序行為。 Apache Digester可以輕松為您完成此任務。 使用Apache Digester相當容易將XML文檔轉換為相應的Java bean對象層次結構。 請參閱…

騰訊云搭svn服務器,騰訊云使用筆記二: 安裝svn服務器及web同步

A01&#xff1a;安裝subversionsudo apt-get install subversionA02:創建倉庫很多目錄可以放subversion文件倉庫&#xff0c;最常見的是/usr/local/svn和/home/svnsudo mkdir -p /home/svn/youshengyousesudo svnadmin create /home/svn/youshengyouse//說明&#xff1a;先創建…

python將圖像轉換為8位單通道_使用Python將圖片轉換為單通道黑白圖片

本文介紹如何使用python將圖片轉換為純黑白的單通道圖片。文中用到的腳本支持彩色、灰度、帶alpha通道的輸入圖片以及SVG矢量圖&#xff0c;支持調整輸出圖片大小以及設置灰度閾值。最后介紹如何輸出SSD1306 OLED顯示屏可用的XBM文件&#xff0c;并利用輸出的XBM數據在0.96寸的…

Java FlameGraph 火焰圖

上周一個偶然的機會聽同事提到了Java FlameGraph&#xff0c;剛實驗了一下&#xff0c;效果非常好。 一、什么是FlameGraph 直接看圖說話。FlameGraph 是 SVG格式&#xff0c;矢量圖&#xff0c;可以隨意擴大縮小&#xff0c;看不清的信息可以放大看。圖中&#xff0c;各種紅橙…

ADB 常用命令

獲取Android設備號 adb shell getprop ro.serialno 獲取系統版本 adb shell getprop ro.build.version.release>4.2.2 獲取系統api版本 adb shell getprop ro.build.version.sdk>17 獲取設備分辨率&#xff08;SDK4.3&#xff09; adb shell wm size獲取設備屏幕密度&am…

哪個Java線程消耗了我的CPU?

當您的Java應用程序占用100&#xff05;的CPU時&#xff0c;您該怎么辦&#xff1f; 事實證明&#xff0c;您可以使用內置的UNIX和JDK工具輕松找到有問題的線程。 不需要探查器或代理。 為了進行測試&#xff0c;我們將使用以下簡單程序&#xff1a; public class Main {publi…