DDD,封装和分层架构:我的域名是否过于贫血?
我目前正在使用.net和nhibernate为旅游行业的客户开发一些相当大的应用程序,并且我遇到了一些实施DDD的问题,以及团队内部就最佳方式进行分歧的问题.我希望有人可以提供一些指导.
目前,我们已经在域外实现了一个服务层,每个聚合根([EntityName]服务)都有一个服务. 这些服务包含对存储库的注入引用(这些引用在其他地方都没有引用),并且还负责所有保存/更新行为和管理事务性. 我的主要问题是: >服务层是否应包含如此多的逻辑?如果不是在哪里 编辑 感谢@ david-masters和@ guillaume31精心设计的答案. 你帮助我解决了我感觉到的“臭味代码”. 首先,我应该说我们有一个(非常)传统的oracle DB来应对,因此Id生成要求(以及其他问题). 对于任何看过这个问题的人来说,这两个答案都提出了很好的建议,但对我来说,这是最好的建议: “从务实的角度来看,我会问自己:如果我想参与我的Domain层的一部分并在另一个应用程序中重用它,它是否包含我在新应用程序中利用域所需的所有业务规则和行为?如果没有,那么可能意味着当前在应用程序端的一些部分需要移动到域层.“ 考虑到这一点,我重新评估了我们的域和服务层,现在我相信我已经解决了我们的设计问题 解决方法
我假设你在这里谈论Application层中的服务,而不是Domain层.看起来你的域名对象几乎是贫血的,有些人认为这是一种反模式,但对此有很多争论. 从务实的角度来看,它是否包含在新应用程序中利用域所需的所有业务规则和行为?如果没有,则可能意味着当前在应用程序端的某些部分需要移动到域层. 请注意,我在这里谈的是纯粹的域业务规则,而不是特定于应用程序的规则.例如,某些操作必须通过具有4个步骤的向导执行,在最后一步结束时要求用户进行确认,并且在最后一步之后将所有修改刷新到持久性存储中特定的业务规则,而不是域规则.因此,不应将它们移动到Domain层.
IMO一个聚合根不应该拥有对它自己的存储库的引用,并且知道如何存储它自己,因为它打破了持久性的无知,并在域对象中引入了一个额外的责任,这将使它混乱.但是,聚合根可能偶尔会持有对另一个实体的存储库的引用.
我会说有两种类型的交易: >“应用程序”层中的“用户”事务,也称为“工作单元”.这些是跨越用例的高级事务,或者是Web应用程序中网页生命周期的最后一个事务(“在视图中打开会话”). ORM框架通常提供管理这些事务的工具.
是的,实体有时可以调用域服务.域服务包含不属于任何实体的域规则和行为.您可以对这些依赖项进行硬编码或将它们注入实体中,具体取决于所需的分离级别.
我不建议为按需访问的实体生成ID生成.正如大卫指出的那样,当你新建实体时,在语言层面生成一个Guid通常是个更好的主意. 如果您仍想要ID生成路由,则调用ID生成器通常是您的实体的Factory而不是实体本身的作业. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |