假设我有一堆用于抽象模块的集成:parser
和ordering
。
从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中,存储库表示检索和修改聚合根。一些翻译确实很适合存储库模式,您可以按照它对它们进行建模。然而,其中一些可能更适合域服务。就像任何其他存储库和域服务一样,您可以将集成服务的抽象放在域包中,而将它们的实现放在不同的包中。