问题描述
编辑:这不是在理论层面上的冲突,而是执行级别的冲突。 另一个编辑:
问题是没有域模型作为仅数据/ DTO而不是更丰富,更复杂的对象映射,其中Order具有OrderItems和一些calculateTotal逻辑。具体问题是,例如,订单需要从中国的某些网络服务中获取OrderItem的最新批发价格(例如)。所以你有一些Spring服务运行,允许在中国的这个PriceQuery服务的调用。订单有calculateTotal遍历每个OrderItem,获取最新的价格,并将其添加到总计。
那么你如何确保每个订单都有一个这个PriceQuery的引用服务?如何在解除序列化,从DB加载和新鲜的实例化之后恢复它?这是我的确切问题。
简单的方法是传递对calculateTotal方法的引用,但如果您的Object在其整个生命周期内部使用此服务,该怎么办?如果用于10种方法怎么办?每个时间都会引起困扰。
另一种方法是将calculateTotal移出订单并进入OrderService,但这会打破OO设计,我们走向旧的事务脚本的方式。
原始帖子:
简版:
丰富的域对象需要引用许多组件,但是这些对象可以被持久化或者被序列化,所以它们对外部组件(Spring bean在这种情况下是服务,存储库,任何东西)所持有的引用是暂时性的,并被消除。当对象被取消序列化或从数据库加载时,需要重新注入它们,但这是非常难看的,我看不到一种优雅的方式来实现。
更长的版本:
一段时间以来,我在Spring的帮助下练习了松耦合和DI。它帮助我很多东西可以管理和可测试。不过之前,我读过域驱动设计和一些马丁·福勒。因此,我一直在尝试将简单的DTO(通常是表行的简单表示,只是数据无逻辑)转换为更丰富的域模型。
随着我的域名增长并承担新的职责,我的域对象开始需要我在Spring环境中拥有的一些bean(服务,存储库,组件)。这很快就成为一个噩梦,也是转化为富域设计的最困难的部分之一。
基本上,我手动注入了一个对应用程序的引用上下文进入我的域:
- 当从Repository或其他负责实体加载对象时,由于组件引用是短暂的,显然不会被持久化
- 当从Factory创建对象时,由于新创建的对象缺少组件引用
- ,当对象在Quartz作业中被取消序列化或其他首先,它是丑的,因为我传递对象的应用程序上下文引用,并期望它通过名称引用它需要的组件。这不是注入,它是直接拉。
其次,这是丑的代码,因为在所有提到的地方,我需要注入appContext的逻辑
第三,它是容易出错的,因为我必须记住在所有这些地方注入所有这些对象,这比这更难听。
有一个更好的方法,我希望你可以点亮它。
解决方案ve找到答案,至少对于那些使用Spring:
Edit: This is not a conflict on the theoretical level but a conflict on an implementation level.
Another Edit:The problem is not having domain models as data-only/DTOs versus richer, more complex object map where Order has OrderItems and some calculateTotal logic. The specific problem is when, for example, that Order needs to grab the latest wholesale prices of the OrderItem from some web service in China (for example). So you have some Spring Service running that allows calls to this PriceQuery service in China. Order has calculateTotal which iterates over every OrderItem, gets the latest price, and adds it to the total.
So how would you ensure that every Order has a reference to this PriceQuery service? How would you restore it upon de-serializations, loading from DBs, and fresh instantiations? This is my exact question.
The easy way would be to pass a reference to the calculateTotal method, but what if your Object uses this service internally throughout its lifetime? What if it's used in 10 methods? It gets messy to pass references around every time.
Another way would be to move calculateTotal out of the Order and into the OrderService, but that breaks OO design and we move towards the old "Transaction Script" way of things.
Original post:
Short version:Rich domain objects require references to many components, but these objects get persisted or serialized, so any references they hold to outside components (Spring beans in this case: services, repositories, anything) are transient and get wiped out. They need to be re-injected when the object is de-serialized or loaded from the DB, but this is extremely ugly and I can't see an elegant way to do it.
Longer version:For a while now I've practiced loose coupling and DI with the help of Spring. It's helped me a lot in keeping things manageable and testable. A while ago, however, I read Domain-Driven Design and some Martin Fowler. As a result, I've been trying to convert my domain models from simple DTOs (usually simple representations of a table row, just data no logic) into a more rich domain model.
As my domain grows and takes on new responsibilities, my domain objects are starting to require some of the beans (services, repositories, components) that I have in my Spring context. This has quickly become a nightmare and one of the most difficult parts of converting to a rich domain design.
Basically there are points where I am manually injecting a reference to the application context into my domain:
- when object is loaded from Repository or other responsible Entity since the component references are transient and obviously don't get persisted
- when object is created from Factory since a newly created object lacks the component references
- when object is de-serialized in a Quartz job or some other place since the transient component references get wiped
First, it's ugly because I'm passing the object an application context reference and expecting it to pull out by name references to the components it needs. This isn't injection, it's direct pulling.
Second, it's ugly code because in all of those mentioned places I need logic for injecting an appContext
Third, it's error prone because I have to remember to inject in all those places for all those objects, which is harder than it sounds.
There has got to be a better way and I'm hoping you can shed some light on it.
解决方案I've found the answer, at least for those using Spring:
6.8.1. Using AspectJ to dependency inject domain objects with Spring
这篇关于如何解决松散耦合/依赖注入与富域模型之间的冲突?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!