在DDD中放置业务逻辑的位置

Vex*_*Vex 9 domain-driven-design business-logic service-layer

我正在试图找出构建易于维护和可测试的架构的最佳方法.经历了几个项目之后,我看到了一些非常糟糕的架构,我想避免在我自己的项目中犯下未来的错误.

假设我正在构建一个相当复杂的三层应用程序,我想使用DDD.我的问题是,我应该在哪里放置我的业务逻辑?有人说它应该放在服务(服务层)中,这确实有意义.拥有一系列遵循单一责任原则的服务是有道理的.

但是,有些人说这是反模式,业务逻辑不应该在服务层实现.为什么是这样?

假设我们有IAuthenticationService一个带bool UsernameAvailable(string username)签名的方法.该方法将实现所有必需的逻辑以检查用户名是否可用.

根据"这是一个反模式"的人群,这里有什么问题?

Jef*_*nal 13

如果您将所有业务逻辑放在(隐式无状态)服务层中,那么您将编写过程代码.通过将行为与数据分离,您将放弃编写面向对象的代码.

这并不总是坏事:它很简单,如果你有简单的业务逻辑,就没有理由投资一个成熟的面向对象的领域模型.

业务逻辑越复杂(域越大),程序代码转换成意大利面条代码越快:程序开始以不同的前后条件(以不兼容的顺序)互相调用,并且它们开始需要不断增长的状态对象.

Martin Fowler关于贫血领域模型的文章可能是理解为什么(以及在什么条件下)人们反对将业务逻辑放在服务层中的最佳起点.


Dav*_*all 5

服务层本身不是反模式,它是放置业务逻辑的某些元素的一个非常合理的地方.但是,您需要对服务层的设计应用自由裁量权,确保您不会从域模型和构成它的对象中窃取业务逻辑.

通过这样做,你可以得到一个真正的反模式,贫血领域模型.Martin Fowler 此对此进行了深入讨论.

您的IAuthenticationService示例可能不是最好的讨论问题 - 许多围绕身份验证的逻辑可以被视为生活在服务中而不是真正与域对象相关联.一个更好的例子可能是,如果您有某种IUserValidationService来验证用户,或者甚至更糟糕的是执行类似流程订单的服务 - 验证服务正在从用户对象中剥离逻辑,并且订单处理服务正在从逻辑中取出逻辑您的订单对象,也可能来自代表客户的对象,交货通知等......

  • @Vex:人们通过"服务层"来表示很多不同的东西,但是如果你试图将所有**业务逻辑**放入你的域模型中,你就不会出错.(与**应用逻辑**相反 - 请参阅[此答案](http://stackoverflow.com/questions/2475136/how-useful-is-a-pure-mvc-implementation/2479207#2479207)了解更多信息这种区别.) (2认同)

Vad*_* S. 5

使用 DDD 必须有 4 层:表示层、应用程序层、域层和基础设施层。

\n

表示层向用户呈现信息,解释用户命令。

\n

所有依赖于用例逻辑(应用程序实体、应用程序工作流组件,例如 DTO、应用程序服务)的内容都进入应用程序层(应用程序逻辑)。该层不包含任何业务逻辑,不保存业务对象的状态,可以保存应用程序任务进度的状态。

\n

用例逻辑(业务实体、业务工作流组件,例如域模型、域服务)的所有不变性都进入域层(域逻辑)。该层负责业务领域的概念和业务规则。

\n

基础设施层可能有 IoC、缓存、存储库、ORM、密码学、日志记录、搜索引擎等。

\n