在我的应用程序中有几层 . 本主题将重点介绍域和基础结构层 .
我在域层中有存储库接口ClientRepositoryInterface . 我在Infrastructure层中实现了此接口ClientRepositoryImpl .
但是为了在其存在的循环中间重构对象,我需要工厂(ReconstitutionClientFactory) . 调用工厂将在存储库中 . 埃里克埃文斯的书被描述为正常的做法 .
但是应该找到这个工厂(ReconstitutionClientFactory)?在域或基础架构层?
我想在域......但是!但是下层将直接调用更高层!这是错的,但怎么做对了?
2 回答
首先,层方法有点过时了 . 在谈论层次时,思考“背景”,谁更重要的是谁 .
存储库负责 restoring 一个对象 . 一家工厂只是 creates 一个新对象 . 注意不同的语义 . 存储库知道如何完成对持久性的保存/恢复,这取决于存储和访问方法 .
因此,一切都在存储库内完成,即在基础结构中完成 . 如果你序列化了东西,那么你只需要反序列化(这就是文档数据库做事情的方式) . 如果您正在使用ORM或在表中存储内容,那么您将执行获取数据和重新填充对象所需的所有查询 . ORM是最简单的方法,因为它可以使用反射来填充私有属性 . 在这种情况下,ORM本身就是工厂 .
还有一件事,即恢复,虽然技术上可以由域工厂完成,但工厂的目的并不是因为它打破了层边界 . 我们希望保持基础架构中的所有持久性相关 .
工厂和存储库概念
为了回答你的问题,我认为重点关注DDD定义的概念的责任 .
在蓝皮书中,有一节介绍了您描述的问题:
并特别针对您的问题:
(埃文斯的引言,第6章,“与工厂的关系”一节)
为了使概念保持纯净,重要的是工厂和存储库的接口是干净的 . 因此,不要通过工厂界面查询现有的 .
保持接口清洁并不意味着您不应该使用存储库实现中的工厂,因为,毕竟,存储库在某个时刻创建了一个实例,如果该实例创建很复杂,那么工厂就是合适的解决方案 .
再次引用埃文斯:
但请注意,存储库很可能在工厂上调用的方法不同于真正想要创建新域对象的客户端(而不是重构) .
埃文斯的书中甚至有一个例子说明了方法:
回答你的问题
现在很明显这是允许的,让我们关注你的工厂放置问题:
DDD factory interface 属于域,因为您的域逻辑使用它来创建域对象 .
DDD reconstitution factory interface 不属于域,因为这仅与您的存储库相关 . 它不存在于您域的现实世界中 .
现在,如果你're using an architecture that prohibits dependencies from the domain to the infrastructure (which you probably should when applying DDD), it'清楚 the factory implementation belongs in the infrastructure . 请注意,无论您是否调用图层,环,域等,依赖关系都是重要的部分 .