gpt4 book ai didi

domain-driven-design - DDD - 如何在应用层重用代码?

转载 作者:行者123 更新时间:2023-12-05 06:08:34 26 4
gpt4 key购买 nike

如何在没有映射的情况下重用应用层的代码?

让我们使用 AddOrder(OrderDto) 方法创建一个应用程序服务 OrderService。该方法由 rest api 使用。 Controller 方法调用 OrderService.AddOrder(OrderDto) 并将 OrderDto 参数映射到 Order 实体。然后将 Order 实体添加到存储库中。映射在那里完成,因为 OrderService 和 AddOrder 是一个应用程序接口(interface)。

重用代码并不仅从 Controller 调用 OrderService.AddOrder(orderDto) ,而且从 OrderService 中的另一个方法甚至从另一个应用程序服务调用 OrderService.AddOrder(orderDto) 会很好。

但是,在调用另一个应用程序方法之前,总是需要在应用程序服务方法内部从一个实体映射到 DTO,然后将结果从 DTO 映射回实体。

=> 同层无用映射。随着系统变得越来越大,它最终会到处映射到 DTO。不好。

最好避免内部映射,只在应用程序界面的顶部进行映射。我们可以编写一个服务,在参数中接受域模型(实体)而不是 DTO:OrderDomainService.AddOrder(order)。

这解决了“映射问题”。领域服务可以相互调用,无需映射,应用服务也可以调用领域服务。但是,这意味着领域服务必须使用基础设施层的存储库来加载数据,因为我们将代码从应用程序服务方法移到了领域服务方法。这会创建从领域层到基础设施层的依赖关系。

=> 错误的依赖关系。基础架构应该依赖于领域,而不是领域依赖于基础架构。

如何解决?

应用程序服务不应包含带有域模型类型参数的方法。域服务不能使用存储库。

那么可重用的代码在哪里写呢?

或者我错了,域服务可以使用存储库。通过域层中的接口(interface),它不会直接依赖于基础设施层。然而,它最终会以 Controller 方法调用应用程序服务方法调用域服务方法结束。

最佳答案

在重用逻辑方面,我认为您正朝着领域服务的方向前进。应用程序服务适用于编排特定用例,并且仅以正确的顺序调用不同的操作。领域逻辑应该始终在领域层。

关于基础架构依赖性:为了在 DDD(或干净的架构)中使用存储库,存储库接口(interface) 应该位于领域层,而这些接口(interface)的具体实现位于基础结构层

那么应用层和领域层都应该依赖于接口(interface)而不是基础设施层。

The domain service can't use repository.

因此它可以通过依赖于存储库接口(interface)来使用存储库,而具体的基础设施存储库是在依赖注入(inject)之后在运行时注入(inject)的。

However then it would end up with a controller method calling an application service method calling an domain service method.

如果因为不需要真正的编排而没有合理的应用程序服务,那么在让 Controller 直接调用域类时至少不要破坏任何依赖性规则,例如如果用例太简单并且不需要 API 层(这里是 Controller )和领域层之间的抽象。但我通常更喜欢使用应用程序服务,因为它们使领域层独立于该外层,并允许领域层和 API 层彼此独立发展。

关于domain-driven-design - DDD - 如何在应用层重用代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65114332/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com