【发布时间】:2017-11-21 02:19:33
【问题描述】:
问题:我是否应该改变我的依赖关系并让DomainModel 依赖于Core(它包含系统接口和高级策略)?
我们是否考虑过用丰富的域模型来表示实现细节?
背景:所以我的DomainModel 在一个单独的项目中,没有传出依赖项。我所有的子系统服务都在单独的项目中,并且它们都不知道彼此。我还有一个Core 项目,它包含所有系统特定的东西,例如接口、枚举、验证类、扩展和其他所有服务共有的东西,我不会将它们归类为低级实现细节。 Core 除了对DomainModel 没有外向依赖,所有服务都依赖于Core 和DomainModel。
我目前的想法:所以我听说过诸如
之类的设计声明“领域模型应该没有外向依赖”
和可能对比
“高级策略不应依赖于低级实现细节”
和
“模块应该在稳定的方向上相互依赖”
我发现当我开发系统时,领域模型的实现发生了很大变化,所有的业务规则和对象都在那里,我认为大多数领域模型根本就不是稳定的,可能其中一些是这样的作为ValueObject(s)。
优势我看到 DomainModel 依赖于 Core 的优势在于,高级策略然后对域模型的实现细节一无所知,这也与其余部分隔离系统。事实上,所有其他项目都将只依赖于Core,并且彼此之间仍然一无所知。当我对 DomainModel(我在开发时经常这样做)进行更改时,构建将只重新编译该项目,而不是像目前那样重新编译整个解决方案。
缺点我看到在实现这种额外的松散耦合时会增加复杂性?我必须为每个单独的域模型对象创建接口,这些对象将位于Core 中的一个特殊文件夹中。对于这些接口,我还想删除“I”前缀并说MoneyType : Money [接口]。我想我可以实例化域对象的唯一方法是通过抽象工厂,所以我还需要更多这些。现在我确实喜欢能够在系统中的“任何地方”实例化具体的域对象,几乎就像 BCL 的扩展或抽象(这不是域模型的一部分吗?)。
我可以想象系统可以使用任一架构,所以这只是竞争设计问题的经典案例 - 还是我完全遗漏了什么?
编辑:这个投票率很高的答案似乎表明域模型应该被隔离,每个对象只向系统的其余部分公开一个接口。
https://stackoverflow.com/a/821300/7417812
目前这对我来说感觉更好,因为系统的其余部分无法不受限制地访问域对象(因此每次发生更改时都会重新编译它们)。但是,将这种依赖关系转变为完全隔离并非易事,因此我非常愿意接受更多讨论和答案。
更多编辑:所以我尝试了重构,当我开始尝试实现我自己的简单 DI 容器时,我觉得事情开始变得很臭而且有点可笑。
完全DomainModel 隔离带来的任何好处都被复杂性和代码行数的指数级增长所抵消(至少对我而言)。所以我重构了架构,使DomainModel 只依赖于Core,它现在只通过合同类、自定义集合、注释和我使用的常见扩展来保存我的设计。我将所有特定于系统的接口和基础设施放到一个新项目Infrastructure 中,所有子系统服务都依赖它(这里没有特定技术,所以可能不是典型的基础设施层?)。
现在一切都感觉好多了,但是我又回到了依赖于 concrete 的领域对象,我可以使用这些对象。这根本不是一个浪费的练习,因为我发现了DomainModel 的一些改进和简化,并且能够澄清Core 并确定Infrastructure 的机会。
【问题讨论】:
-
你指的是洋葱架构中的“核心”吗?
-
@ConstantinGALBENU 我实际上并不熟悉该框架,Core 只是我自己的项目名称。
标签: c# oop architecture domain-driven-design