在我的应用程序中有几层。 本主题将重点介绍域和基础架构层。
我在域层中有存储库接口ClientRepositoryInterface。 我在Infrastructure层中实现了此接口ClientRepositoryImpl。
但是为了在它存在的循环中间重建对象,我需要工厂(ReconstitutionClientFactory)。 调用工厂将在存储库中。 Eric Evans的这本书被描述为一种常规做法。
但是应该找到这个工厂(ReconstitutionClientFactory)?在Domain或Infrastructure层?
我认为在域名中...... 但!但是下层会直接调用更高层! 这是错的,但怎么做对了?
答案 0 :(得分:27)
要回答您的问题,我认为专注于DDD定义的概念的职责非常重要。
在蓝皮书中,有一节介绍了您所描述的问题:
FACTORY处理对象生命的开始; REPOSITORY有助于管理中间和结束。
特别针对您的问题:
因为在这种情况下,REPOSITORY是基于数据创建对象,所以很多人认为REPOSITORY是一个工厂 - 从技术角度来看确实如此。
(埃文斯的引言,第6章,第34节;与工厂的关系")
为了使概念保持纯净,重要的是工厂和存储库的接口是干净的。因此,不允许通过存储库界面创建新的业务对象,也不允许通过工厂界面查询现有的业务对象。
保持接口清洁并不意味着您不应该使用来自存储库实现的工厂,因为,毕竟,存储库在某个时刻创建了一个实例,并且如果该实例创建是复杂,工厂是适当的解决方案。
再次引用埃文斯:
每当从另一种介质重构一个物体时,就会出现复杂的情况,那么FACTORY就是一个不错的选择。
但请注意,存储库很可能在工厂上调用的方法与真正想要创建新域对象的客户端相比(而不是重构)。
埃文斯甚至还有一个例子。这本书说明了方法:
现在很明显这是允许的,让我们关注你的工厂放置问题:
DDD工厂界面属于域,因为您的域逻辑使用它来创建域对象。
DDD重建工厂界面不属于域,因为这仅与您的存储库相关。它并不存在于您域的现实世界中。
现在,如果您使用的架构禁止从域到基础架构的依赖关系(在应用DDD时可能应该这样做),那么工厂实现属于基础架构< / strong>即可。请注意,无论您是否调用图层,环,域或其他内容,依赖关系都是重要的部分。
答案 1 :(得分:12)
首先,层方法有点过时了。在谈论层次时,要考虑“背景”,谁更重要的是谁。
存储库负责恢复对象。工厂只需创建新对象。注意不同的语义。存储库知道如何完成对持久性的保存/恢复,这取决于存储和访问方法。
因此,一切都在存储库内完成,即在基础结构中完成。如果你序列化了东西,那么你只需要反序列化(这就是文档数据库做事情的方式)。如果您正在使用ORM或在表中存储内容,那么您将执行获取数据和重新填充对象所需的所有查询。 ORM是最简单的方法,因为它可以使用反射来填充私有属性。在这种情况下,ORM本身就是工厂。
还有一件事,即恢复,虽然技术上可以由域工厂完成,但工厂的目的并不是因为它打破了层边界。我们希望保持基础架构中的所有持久性相关。