逻辑建模与物理建模_架构层和建模域逻辑

逻辑建模与物理建模

在讨论用于建模域逻辑(例如事务脚本,表模块,域模型)的PoEAA模式时,我注意到人们对域模型模式是最好的印象(尽管印象不对)。 因此,他们开始将其应用于所有内容。

不配领域模型模式

让我们成为现实。 大多数子系统都是基于CRUD的。 系统的仅特定部分需要域模型实现模式。 或者,换句话说,应用程序的某些部分仅需要数据上的表格和一些验证逻辑(例如,必填/必填字段,数字的最小/最大值,文本的最小/最大长度)。 对于这些,领域模型是不值得的。

对于这些,也许贫血领域模型会很好地适合。

贫血领域模型并不像听起来那样糟糕

贫血领域模型并不像听起来那样糟糕。 在那儿,我说了(至少在我的博客文章中如此)。

但是看起来怎么样?

类图1

package com.acme.bc.domain.model;
...
@Entity
class Person {@Id ... private Long id;private String firstName;private String lastName;// ...// getters and setters
}
...
interface PersonRepository /* extends CrudRepository<Person, Long> */ {// CRUD methods (e.g. find, find/pagination, update, delete)
}
package com.acme.bc.infrastructure.persistence;
...
class PersonRepositoryJpa implements PersonRepository {...
}

在表示层中,控制器可以访问存储库。 该存储库负责提取持久性详细信息。

package com.acme.bc.interfaces.web;@Controller
class PersonsController {private PersonRepository personRepository;public PersonsController(PersonRepository personRepository) {...}// ...
}

在这种情况下,将Person类暴露给表示层是完全可以的。 表示层可以直接使用它,因为它具有一个公共的零参数构造函数,获取器和设置器,而视图很可能需要这些构造器。

那里有。 一个简单的基于CRUD的应用程序。

您还需要服务层吗? 否。您还需要DTO (数据传输对象)吗? 不需要。在这种简单的CRUD情况下,您不需要其他服务或DTO

是的,此Person看起来像域实体。 不过,这并不包含逻辑,并且只是用来传输数据。 因此,它实际上只是一个DTO。 但这没关系,因为它可以完成保存持久性存储和检索的数据的工作。

现在, 如果业务逻辑开始变得更加复杂,则最初贫乏的领域模型中的某些实体可能会变得更加富有行为。 如果是这样的话,这些实体可以值得一个领域模型模式。

贫血领域模型的替代品

作为贫血领域模型(如上所述)的替代方法,可以将这些类移出领域逻辑层并移入表示层。 而不是命名
PersonRepository ,现在命名为
PersonDao

类图0

package com.acme.bc.interfaces.web;@Entity
class Person {...}@Controller
class PersonsController {private PersonDao personDao;public PersonsController(PersonDao personDao) {...}// ...
}interface PersonDao /* extends CrudRepository<Person, Long> */ {// CRUD methods (e.g. find, find/pagination, update, delete)
}
package com.acme.bc.infrastructure.persistence;class PersonDaoJpa implements PersonDao {...
}

太多分层

我认为,如果您必须通过不增加价值的强制性应用程序服务,那将是一个过大的杀伤力。

package com.acme.bc.interfaces.web;
...
@Controller
class PersonsController {private PersonService personService;public PersonsController(PersonService personService) {...}// ...
}
package com.acme.bc.application;
...
@Service
class PersonService {private PersonRepository personRepository;public PersonService(PersonRepository personRepository) {...}// expose repository CRUD methods and pass to repository// no value add
}

将存储库保留在domain.model包中。 将存储库实现放置在另一个包中(例如, infrastructure.persistence )。 但为什么?

domain.model包是定义存储库的位置。 域模型中的元素指示存储库接口定义中需要哪些方法。 因此,存储库定义放置在domain.model包中。 存储库实现需要遵循添加的新方法(或删除未使用的方法)。 此包装遵循依赖关系反转原理。 infrastructure.persistence程序包取决于domain.model程序包,而不是相反。

交易申请服务

那么,什么时候应用服务合适? 应用程序服务负责驱动工作流程和协调事务管理(例如,通过使用Spring中的声明性事务管理支持)。

如果您发现简单的CRUD应用程序需要在表示层控制器中启动事务,那么将它们移至应用程序服务中可能是一个好兆头。 当控制器需要更新多个不具有单个根的实体时,通常会发生这种情况。 这里通常的示例是在银行帐户之间转移金额。 需要进行交易以确保借方和贷​​方都成功或都失败。

类图2

package sample.domain.model;
...
@Entity
class Account {...}
...
interface AccountRepository {...}
package sample.interfaces.web;
...
@Controller
class AccountsController {private AccountRepository accountRepository;...@Transactionalpublic ... transfer(...) {...}
}

如果看到了这一点,那么最好将其(从表示层)移至应用程序层服务。

package sample.interfaces.web;
...
@Controller
class AccountsController {private AccountRepository accountRepository;private TransferService transferService;...public ... transfer(...) {...}
}
package sample.application;
...
@Service
@Transactional
class TransferService {private AccountRepository accountRepository;...public ... transfer(...) {...}
}
package sample.domain.model;
...
@Entity
class Account {...}
...
interface AccountRepository {...}

复杂逻辑的域模型模式(仅)

我将以重复输入记帐为例。 但我敢肯定,还有更适合的复杂逻辑。

假设我们将日记帐分录和科目建模为域实体。 该帐户包含余额(金额)。 但这并不是一个简单的设定。 需要创建日记帐分录。 过帐日记帐分录时,它将影响指定的帐户。 然后,该帐户将更新其余额。

package ….accounting.domain.model;
...
/** Immutable */
@Entity
class JournalEntry {// zero-sum items@ElementCollectionprivate Collection<JournalEntryItem> items;...
}
...
/** A value object */
@Embeddable
class JournalEntryItem {...}
...
interface JournalEntryRepository {...}
...
@Entity
class Account {...}
...
interface AccountRepository {...}
...
@Entity
class AccountTransaction {...}
...
interface AccountTransactionRepository {...}

现在,在这种情况下,一个简单的实现将有一个表示层控制器创建一个日记帐分录对象,并使用一个存储库来保存它。 并且在某个时间点(或如果使用自动过账),将创建相应的帐户交易,并更新帐户余额。 所有这些都需要汇总成一个事务(即全有或全无)。

同样,此事务理想地移至应用程序服务。

package ….accounting.application;@Service
@Transactional
class PostingService {...}

如果需要允许用户浏览日记帐分录和帐户交易,则表示层控制器可以直接使用相应的存储库。 如果域实体不适合于视图技术(例如,它不遵循JavaBean命名约定),则表示层可以定义适合于视图的DTO。 小心! 不要仅仅为了满足表示层的需求而更改域实体。

package ….interfaces.web;@Controller
class AccountsController {private AccountRepository accountRepository;private AccountTransactionRepository accountTransactionRepository;private PostingService postingService;...
}

即将结束...

所以你有它。 希望这篇文章可以阐明何时(以及何时不)使用域模型模式。

类图3

现在我想我要感冒了。

奶油啤酒

翻译自: https://www.javacodegeeks.com/2016/10/architectural-layers-modeling-domain-logic.html

逻辑建模与物理建模

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

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

相关文章

html文字列表,文字列表模板

文字列表模板1、如何编辑列表模板文字列表模板存放在模板包archive文件夹中&#xff0c;命名以list_text为前缀在模板包中找到list_text.html 模板&#xff0c;复制另存为一个新模板&#xff0c;命名为list_text_自定义名称.html自定义名称可以是英文或拼音&#xff0c;但不能用…

inputstreamreader未关闭会导致oom_Linux内核OOM机制分析和防止进程被OOM杀死的方法...

问题描述Linux 内核有个机制叫 OOM killer(Out-Of-Memory killer)&#xff0c;该机制会监控那些占用内存过大&#xff0c;尤其是瞬间很快消耗大量内存的进程&#xff0c;为了防止内存耗尽而内核会把该进程杀掉。典型的情况是&#xff1a;某天一台机器突然 ssh 远程登录不了&…

centos一键清理磁盘空间_如何清理 Docker 占用的磁盘空间

Docker 很占用空间&#xff0c;每当我们运行容器、拉取镜像、部署应用、构建自己的镜像时&#xff0c;我们的磁盘空间会被大量占用。如果你也被这个问题所困扰&#xff0c;咱们就一起看一下 Docker 是如何使用磁盘空间的&#xff0c;以及如何回收。docker 占用的空间可以通过下…

mongodb dsl_具有Java DSL的Spring Integration MongoDB适配器

mongodb dsl1引言 这篇文章解释了如何使用Spring Integration从MongoDB数据库中保存和检索实体。 为了完成此任务&#xff0c;我们将使用Java DSL配置扩展来配置入站和出站MongoDB通道适配器。 例如&#xff0c;我们将构建一个应用程序&#xff0c;使您可以将订单写入MongoDB存…

Oracle 数据库中较为复杂或典型的 SQL 语句的解读

文章目录批量生成 SQL 语句/拼接字符串多表关联查询 where 子句示例&#xff08;一&#xff09;示例&#xff08;二&#xff09;普通的表间内连接查询语句关键字 distinct 用法说明Oracle 数据库的分组排序查询Oracle 数据库 cast 函数Oracle 数据库 sum 函数的高级用法Oracle…

私有方法与静态私有方法_每个私有静态方法都是新类的候选人

私有方法与静态私有方法您是否有私有的静态方法来帮助您将算法分解为更小的部分&#xff1f; 我做。 每当我编写一个新方法时&#xff0c;我就会意识到它可以是一个新类。 当然&#xff0c;我不会从所有课程中选修课程&#xff0c;但这必须是目标。 私有静态方法不可重用&#…

c语言插入排序_还有这种操作?C语言插入排序算法,一点就透

插入排序算法是所有排序方法中最简单的一种算法&#xff0c;其主要的实现思想是将数据按照一定的顺序一个一个的插入到有序的表中&#xff0c;最终得到的序列就是已经排序好的数据。更多C/C资料群文件&#xff1a;569268376直接插入排序是插入排序算法中的一种&#xff0c;采用…

Mac 如何操控远程的 Windows 电脑

文章目录使用 Remote Desktop Connection for mac 客户端第 1 步&#xff1a;Windows 电脑进行远程设置第 2 步&#xff1a;Windows 电脑设置管理员账号和密码第 3 步&#xff1a;获取 Windows 电脑的 IP 地址第 4 步&#xff1a;Mac 电脑安装远程桌面连接客户端第 5 步&#x…

map iterator_一个简单的Map Iterator性能测试

map iteratorJava Map性能有很多方面可以衡量&#xff0c;但是关键的一个是简单的单线程扫描。 这是一些针对Iterators和Java 8 Map.forEach()简单测试代码&#xff0c;以及一些图形结果。 1.性能测试困难 性能测试是一项非常困难的工作&#xff0c;精确的可重复性测试需要Jav…

学生用计算机中sto,STO 文件扩展名: 它是什么以及如何打开它?

STO 疑难解答常见的 STO 打开问题Ecru Software PRO100 不存在你尝试加载 STO 文件并收到错误&#xff0c;例如 “%%os%% 无法打开 STO 文件扩展名”。 如果是这种情况&#xff0c;通常是因为 你的计算机上没有安装 Ecru Software PRO100 for %%os%%。 由于您的操作系统不知道如…

MacBook 使用 Loopback 录屏和录音频(MacBook 录屏教程/录视频教程/Loopback 教程)

文章目录一、下载软体二、Loopback 界面介绍三、设置系统的声音输入/输出设备&#xff08;一&#xff09;设置声音输入设备&#xff08;二&#xff09;设置声音输出设备四、录制程序中选择声音输入设备五、开始录制一、下载软体 在網路上可以找到破解版的軟體 Loopback 二、L…

惠普照片打印软件_被看错的打印机?原来打印机还可以这么玩

孩提时代&#xff0c;经常弄丢试卷的小值君曾频繁地与打印店打交道&#xff0c;那是我最早接触打印机的时候。白驹过隙&#xff0c;时至当下&#xff0c;打印设备已然成为家庭不可或缺的部分。印象中&#xff0c;打印机要不就是打打文档&#xff0c;要不就是打打照片&#xff0…

戴尔G3笔记本使用U盘重装操作系统

戴尔G3笔记本 下载安装大白菜U盘启动盘制作软件根据使用说明完成启动盘制作下载操作系统ISO文件重启电脑&#xff0c;连续按F12&#xff0c;打开如下界面后选择红色线框选项&#xff1a; 进入PE系统界面&#xff0c;打开【大白菜】&#xff0c;看到如下界面&#xff1a;

valid floating point value什么意思_为什么 0.1 + 0.2 = 0.300000004?

往期热门文章&#xff1a;1、《往期精选优秀博文都在这里了&#xff01;》2、求求你&#xff01;数据库不要再使用外键了&#xff1f;3、还在写慢SQL&#xff1f;4、ELK太笨重了&#xff1f;想放弃&#xff1f;快试试日志系统新贵Loki吧&#xff01;5、谁再悄咪咪的吃掉异常&am…

在抽象类中可以没有抽象方法_是否可以在最终课程中使用抽象方法?

在抽象类中可以没有抽象方法这是最近在Java开发人员工作面试的电话面试中向我的一位读者提出的有趣的Java核心问题之一。 即使他知道你 无法用Java将抽象类定型为final &#xff0c;他对方法的措辞感到困惑。 答案很简单&#xff0c;不&#xff0c;在Java的最终类中不可能有抽…

python二维列表排序_使用Python按顺时针方向排序二维坐标列表?

这应该说明问题&#xff0c;给出一个可视化工具 但对于在同一距离上获得一组点的正确入口点来说&#xff0c;这并不总是有效的import random import pylab import cmath from itertools import groupby pts [(random.randrange(-5,5), random.randrange(-5,5)) for _ in range…

微型计算机生产工艺,bb肥生产设备制造工艺流程

原标题&#xff1a;bb肥生产设备制造工艺流程BB肥生产设备与有机肥设备相比较而言设备相对简单&#xff0c;因而BB肥便具有投资小的优点&#xff0c;而且因其配方灵活&#xff0c;非常适合我国正在推广的测土配方肥的需要&#xff0c;是一种非常适合我国国情的肥料。在发达国家…

devc++鼠标变成了光标_Excel填充别再用鼠标拖拉了!用这4个方法,效率至少高10倍!...

Hello&#xff0c;各位叨友们好呀&#xff01;我是叨叨君~根据下表对照一下自己&#xff0c;在Excel中需要批量填充公式的时候&#xff0c;你是不是还在用鼠标拖拉的方法&#xff0c;将光标放在单元格的右下角&#xff0c;然后按鼠标左键&#xff0c;向下拖动&#xff0c;填充完…

运动基元_开发人员的新分布式基元

运动基元面向对象的基元&#xff08;进程内基元&#xff09; 作为Java开发人员&#xff0c;我非常熟悉面向对象的概念&#xff0c;例如类&#xff0c;对象&#xff0c;继承&#xff0c;封装&#xff0c;多态性等。除了面向对象的概念之外&#xff0c;我还非常熟悉Java运行时。它…

html5网站 500.19错误,WIN7操作系统创建IIS后浏览时提示HTTP500.19错误是怎么回事?如何解决?...

WIN7操作系统创建IIS后浏览时提示HTTP500.19错误是怎么回事&#xff1f;如何解决&#xff1f;作者&#xff1a;兴邦开发部人气&#xff1a;发表时间&#xff1a;2015年05月18日[文章内容简介]&#xff1a;WIN7操作系统创建IIS后浏览时提示HTTP500.19错误是怎么回事&#xff1f;…