一尘不染

如何解决松散耦合/依赖性注入与富域模型之间的冲突?

java

编辑: 这不是理论上的冲突,而是实现上的冲突。

另一个编辑: 问题不是将域模型作为仅数据/
DTO,而是将Order具有OrderItems和一些calculateTotal逻辑的更丰富,更复杂的对象映射。特定的问题是,例如,当Order需要从中国的某个Web服务中获取OrderItem的最新批发价格时(例如)。因此,您正在运行一些Spring
Service,可以在中国调用该PriceQuery服务。订单具有calculateTotal,可迭代每个OrderItem,获取最新价格,并将其添加到总计中。

那么,您如何确保每个订单都具有对此PriceQuery服务的引用?在反序列化,从数据库加载以及新的实例化后如何恢复它?这是我的确切问题。

最简单的方法是将引用传递给calculateTotal方法,但是如果您的对象在其整个生命周期中都在内部使用此服务怎么办?如果有10种方法使用该怎么办?每次传递引用都很麻烦。

另一种方法是将calculateTotal移出Order,然后移入OrderService,但这会破坏OO设计,而我们将采用旧的“事务脚本”方法。

原始帖子:

简短版本: 富域对象需要引用许多组件,但是这些对象会被持久化或序列化,因此它们对外部组件(在这种情况下为Spring
Bean:服务,存储库等)的所有引用都是瞬态的,并且会被清除。从数据库反序列化或加载对象时,需要重新注入它们,但这非常丑陋,我看不到一种完美的方法。

较长的版本:
一段时间以来,我已经在Spring的帮助下练习了松散耦合和DI。它使我对事情保持可管理性和可测试性有很大帮助。但是,不久前,我阅读了域驱动设计和一些Martin
Fowler。结果,我一直试图将域模型从简单的DTO(通常是表行的简单表示,只是没有数据的逻辑)转换成更丰富的域模型。

随着我的领域的发展并承担新的职责,我的领域对象开始需要我在Spring上下文中拥有的一些bean(服务,存储库,组件)。这已迅速成为一场噩梦,并且是转换为富域设计的最困难部分之一。

基本上,有些地方需要手动将对应用程序上下文的引用注入到我的域中:

  • 从组件库或其他负责实体加载对象时,因为组件引用是瞬时的,并且显然不会持久化
  • 从工厂创建对象时,因为新创建的对象缺少组件引用
  • 当对象在Quartz作业或其他地方反序列化时,由于擦除了瞬态组件引用,

首先,这很丑陋,因为我正在向对象传递一个应用程序上下文引用,并期望它通过名称引用将其提取到所需的组件。这不是注入,而是直接拉动。

其次,这是丑陋的代码,因为在所有上述提到的地方,我都需要逻辑来注入appContext

第三,它容易出错,因为我必须记住在所有这些位置为所有这些对象注入内容,这比听起来要难。

必须有更好的方法,我希望您能对此有所了解。


阅读 231

收藏
2020-12-03

共1个答案

一尘不染

我找到了答案,至少对于那些使用Spring的人来说:

6.8.1。使用AspectJ通过Spring依赖注入域对象

2020-12-03