DDD文件夹结构:将存储库拆分到不同的文件夹中,还是将所有业务规则保留在一个通用文件夹中?



假设我有一堆用于抽象模块的集成:parserordering

从DDD的角度来看,组织文件夹结构的更好的方法是什么?

ordering/
----abstract.py
parser/
----abstract.py
integration1/
----ordering.py  # depends on ordering.abstract
----parser.py  # depends on parser.abstract
integration2/
----ordering.py  # depends on ordering.abstract
----parser.py  # depends on parser.abstract

ordering/
----abstract.py
----integration1.py  # depends on abstract
----integration2.py  # depends on abstract
parser/
----abstract.py
----integration1.py  # depends on abstract
----integration2.py  # depends on abstract

抽象文件处理我的应用程序的业务规则(我们如何验证数据,我们如何编排请求-响应周期等),集成文件处理第三方的业务规则(我们如何解释他们发送的数据,我们如何以他们期望的方式准备数据等)。

在我看来,每个集成都充当某种存储库,其核心实现依赖于abstract.py

我倾向于第一种方法,因为我们清楚地分离了这些域,但同时所有文件都有相同的目的。

你是怎么想的?

这里有两个问题:在域层使用抽象和集成外部上下文。

领域层中的抽象

抽象文件处理应用程序的业务规则(如何验证数据,如何编排请求-响应周期等)

仅构成其依赖的抽象(即其他语言中的接口,您需要找到与之类似的Python)的域层(或包),并从不同的包注入它们的具体实现是一个很好的实践。这使得域层独立于基础设施。有一种促进这种实践的体系结构模式,称为端口和适配器体系结构。你的第一个提案多少暗示了这种模式。

此外,在DDD中,大多数业务规则由主要构造强制执行:聚合根(域中最突出的实体)、实体值对象。所有这些都是作为具体类型实现的,不需要将它们抽象出来。诸如存储库域服务等依赖关系被抽象。

下面是一个可能的目录方案,当然可以修改,但要遵守我提到的约定:

.
../domain
..../model
....../entity1
....../value object 1
....../entity2
..../services
....../service1 (interface)
....../service2 (interface)
..../repositories
....../repository1 (interface)
....../repository2 (interface)
../port
..../adapter
....../services
......../service1 (concrete)
......../service2 (concrete)
....../repositories
......../repository1 (concrete)
......../repository2 (concrete)

集成外部上下文

…集成文件处理第三方的业务规则(我们如何解释他们发送的数据,我们如何以他们期望的方式准备数据,等等)

集成外部上下文(DDD术语中的上下文映射)本身就是一个挑战。DDD的策略部分处理这个问题,并根据上下文之间关系的性质,为集成上下文推荐几个选项。所有选项都力求确保与外部上下文的交流经过一些翻译过程;

在我看来,每个集成都充当某种存储库,其核心实现依赖于abstract.py。

在DDD中,存储库表示检索和修改聚合根。一些翻译确实很适合存储库模式,您可以按照它对它们进行建模。然而,其中一些可能更适合域服务。就像任何其他存储库和域服务一样,您可以将集成服务的抽象放在域包中,而将它们的实现放在不同的包中。