在哪里放置需要从数据库中获取数据的域逻辑

Posted

技术标签:

【中文标题】在哪里放置需要从数据库中获取数据的域逻辑【英文标题】:Where to put domain logic which needs to fetch data from database 【发布时间】:2011-08-25 23:45:54 【问题描述】:

我知道域逻辑应该放在域对象中。但是,如果我的域逻辑需要来自数据库的数据怎么办? (例如检查唯一值、计算值等)我认为将存储库注入我的域对象不是正确的事情。此外,服务层不应包含业务规则。那么如何解决这种业务逻辑呢?

【问题讨论】:

【参考方案1】:

你是对的,你的域对象不应该直接从数据库中读取数据。这里的经典错误是域对象通过 Web 服务发送并尝试从数据库中读取数据,而它位于服务器上而无法访问数据库。

有几种方法可以做到这一点:

服务层预加载域对象需要的任何信息 域对象可以调用从数据库中获取数据的帮助程序或存储库

【讨论】:

就个人而言,我更喜欢第二种方法。另一个需要提到的重点是存储库应该被抽象出来,这样域对象/层就不会与存储库紧密耦合。【参考方案2】:

我一直认为服务层是调用此类活动的合理位置 - 但正如我将解释的那样,这本身并不是我实现它的地方。由于服务层是您进入域的网关,因此您可以放心,无论什么请求启动对这些数据的需求,它都必须通过这一点才能到达那里。

此外,让服务与其他服务对话是非常干净的,因为它们是专门设计为需要最少的努力来调用的。您可以在存储库中公开所需的足够功能(即,可以为您提供匹配 Y 条件的 X 对象的计数的方法/查找器/查询)并将其包装在方便的服务调用中。这不仅使您能够更轻松地在单个服务中完成任务,而且您还可以在服务之间利用此功能来满足更复杂的需求。

我理解将业务逻辑置于服务层的担忧,但根据需求,什么是业务逻辑和什么是特定于实现的业务逻辑之间有一条细线。在编写系统时,通常会出现一些规则,这些规则被暗示为业务逻辑,但不适合。唯一约束是我发现的最常见的例子。请记住,就像存储库中的所有其他内容一样,这不是服务层中的实现,而是对域中已有内容的抽象。

我所做的是将“逻辑”本身放在域中,通常以规范模式实现的形式。由于逻辑在存储库中执行并且不需要更改服务层,因此我已经同意这是完全可以接受的。您会发现适用于实体集合的规则通常是“有趣的”规则。如果您只需要通过聚合根中的集合来验证某些内容是否唯一,那么这很简单。

我见过领域对象了解存储库的方法,但我个人不是粉丝。对我来说,存储库是域如何与持久层交互的定义(尽管并不总是实现)。一个实体甚至知道它有比仅仅存在更重要的目的这一事实使事情变得非常复杂。

【讨论】:

以上是关于在哪里放置需要从数据库中获取数据的域逻辑的主要内容,如果未能解决你的问题,请参考以下文章

使用 curl 从 mailchimp 获取数据我在哪里将 api 密钥放在 curl 调用中

从数据库获取事件并放置日历视图(android)

Flux 应用程序中的缓存逻辑应该放在哪里?

从哪里获取 csv 样本数据? [关闭]

从哪里获取地理数据?

从另一个 DAO 调用一个 DAO?