首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >何时以及为什么要使用域服务?

何时以及为什么要使用域服务?
EN

Stack Overflow用户
提问于 2016-11-11 12:40:40
回答 2查看 138关注 0票数 1

我有一个出租实体,它是一个聚合根。除其他外,它还维护一个分配列表(保留的时间块)。

如何添加新的分配?因为租房是聚合根,所以任何新的分配都应该经过它,但是在我们尝试将租金保存到数据库之前,不可能知道是否可以分配租金。在此期间,另一个用户可以预订它。我猜,我应该用域服务来做这个吗?

每当我需要一个新的租房时,我都不想注入任何东西,但是除了术语不同之外,注入域服务而不是存储库有什么区别呢?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-11-11 15:46:21

何时以及为什么要使用域服务?

使用域服务允许聚合运行查询。税收计算是一个不时出现的例子。聚合将某种状态传递给计算器,计算器报告税收,聚合决定如何处理该信息(忽略它,拒绝需要它的更新,等等)。

运行查询不会以任何方式修改域服务实例,因此您可以任意频繁地重复查询,而不必担心计算会相互污染。

请考虑只读服务提供商。

因为租房是聚合根,所以任何新的分配都应该经过它,但是在我们尝试将租金保存到数据库之前,不可能知道是否可以分配租金。在此期间,另一个用户可以预订它。我猜,我应该用域服务来做这个吗?

不-完全错误的用例。

如果分配是租赁总量的一部分,那么让租房总量创建自己的分配是很好的。您不需要为此提供服务(如果您喜欢分离关注点,您可能会将工作委托给工厂)。

如果“另一个用户可以在此期间保留该分配”,那么您就会发生争用--两个用户试图同时更改相同的聚合。这通常有两种管理方式之一。

锁定:您一次只允许一个用户修改租赁聚合。因此,在数据竞赛中,输家必须等待胜利者完成,然后集合可以拒绝输家的命令,因为特定的分配已经被接受了。

乐观并发:允许两个用户同时修改聚合的不同副本,但只有在原始状态不变的情况下才允许保存。想一想“比较和交换”;这两个指令之间的竞争就在保存中。

代码语言:javascript
运行
复制
state.compareAndSwap(originalState, loserState)
state.compareAndSwap(originalState, winnerState)

胜利者的比较和交换成功,但输家的失败(因为originalState != winnerState),因此输家修改被拒绝。

无论哪种方式,只允许对数据库进行一次写入,保留分配。

如果我对你的理解是正确的,你是说在这种情况下,可以在出租域实体中使用存储库吗?

不,您不应该需要-分配,作为租赁聚合的一部分,由内存中的聚合创建,并且在保存聚合时首次出现在您的数据存储中。

如果所有重要的事情都必须提取到周围的代码或工厂中,那么为什么要使用聚合呢?

这里的一些答案是关注点的分离--聚合的主要关注点是执行业务不变:确保创建具有某种特定状态的分配与其他一切都是一致的。工厂负责确保所创建的对象连接正确。

使用您的例子:工厂将负责在内存中创建分配,但是不需要知道任何关于确保分配是唯一的。聚合描述并强制执行用于确保分配是唯一的规则。

票数 2
EN

Stack Overflow用户

发布于 2016-11-11 13:09:22

使用静态工厂方法创建租房对象。

代码语言:javascript
运行
复制
public static class RentalFactory
{
    public Rental CreateRental()
    {
        var allocationSvc = new RentalAllocationService();
        return new Rental(allocationSvc);
    }
}

存储库应该只关注底层存储的持久性。域服务主要关注的是执行一些涉及实体或值对象的行为。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40548251

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档