我目前正在使用 .net 和 nhibernate 为旅游行业的客户开发一些相当大的应用程序,并且在实施 DDD 时遇到了一些问题,并且团队内部在最佳方式上存在分歧。我希望有人可以提供一些指导。
目前,我们已经在域外实现了一个服务层,每个聚合根([EntityName]Service)都有一个服务。所有其他层使用这些服务通过 GetByThis() 和 GetByTheOther() 等方法获取对聚合根的引用。我们从其他层对域的所有调用都是通过这些服务进行的。
这些服务持有对存储库的注入引用(在其他任何地方都没有引用),并且还负责所有保存/更新行为和管理事务性。服务方法越来越复杂,有时具有似乎属于域的行为,例如条件创建逻辑(如果 property = this 将子对象设置为某物,否则为其他东西)。我们的域实体大多具有简单的方法,例如 GetByThis() 和 HasAThing()。我觉得我们正在失去我们领域的表现力。
我的主要问题是:
- 服务层应该包含这么多逻辑吗?如果不是,它应该去哪里?如果是域,聚合根是否应该包含对存储库的引用?如果是,如何将这些注入(注入创建聚合根的工厂?)
- 应如何处理事务性?
- 实体(或聚合根)是否应该持有对域服务的引用?如果是这样,他们应该如何获得参考资料?
- 为了获得实体的新 id,我们必须调用一个存储过程,该过程已包装在存储库中。你会在哪里引用这个?需要创建许多子实体的实体上的一些复杂方法需要引用这个?
编辑
感谢@david-masters 和@guillaume31 的深思熟虑的回答。
你帮助我解决了我得到的那种“臭代码”的感觉。
首先,我应该说我们有一个(非常)遗留的 oracle DB 来应对,因此需要 Id Generation(以及其他问题)。
对于其他看到这个的人来说,这两个答案都给出了很好的建议,但对我来说,这是最好的建议:
“从务实的角度来看,这就是我会问自己的问题:如果我想在另一个应用程序中使用我的域层的一部分并重用它,它是否包含我在新应用程序中利用域所需的所有业务规则和行为? 如果不是,那么可能意味着当前在应用程序端的一些部分需要移动到领域层。”</p>
考虑到这一点,我重新评估了我们的域和服务层,现在相信我已经解决了我们的设计问题