域驱动设计与命令模式 - 互斥?

use*_*553 2 domain-driven-design command-pattern

tl; dr:
我喜欢Command-pattern的小型,专注的类,SetProjectAsActiveCommand但我也是DDD让模型负责自己的核心业务功能的方法,比如调用Project::setAsActive().这两个想法可以一起工作,还是它们是互斥的架构?
/ tl;博士

我一直工作在一个项目中,我们已经使用了Command模式,它具有类,如过去的几个月里ProposeNewProjectCommand,SetProjectAsActiveCommandAddCommentToProjectCommand,所有这一切都是由一个命令总线处理.这些课程往往相当小,专注,只做一件事.

最近我一直在阅读有关领域驱动设计(DDD)和我推测,这种方法更依赖于模型做自己的工作,所以上面的命令可能被替换Organisation::proposeNewProject(),Project::setAsActive()Project::addComment().

在模型上使用这些方法意味着它们可以充当"聚合根" (例如,在上面的示例中,Project负责创建自己的注释).

虽然我非常喜欢让我的实体对其核心业务功能负有更多责任的想法,但我也担心我的模型可能变得非常非常大,有很多关于应用程序可以执行的各种操作的方法.

有没有办法让Command模式的小型,专注的类仍然使模型一流的公民负责他们的关键业务功能,如在DDD?还是解决潜在大型模型问题的方法?

或者,或者,我应该选择一种模式并专门使用它?


哈里森,提前感谢您提出的任何见解

PS.我从来没有真正研究过使用DDD的应用程序,所以如果这是一个非常天真的问题我会道歉.

小智 6

是什么让它成为DDD,是因为你开始更多地考虑语言,你试图在代码中找到一个与你对域的理解"同步"的模型.实际的实现模式是实现细节.例如,我们可以尝试是否有更好的表达命令的方法,例如SetProjectAsActiveCommand - > ActivateProject; AddCommentToProjectCommand - > CommentOnProject.我们摆脱了开发人员语言(set,add,command),转而使用域语言.

在这种方法中,命令不做任何事情(它们不像GoF命令).它们只是消息,代表用户的意图.聚合(和实体,值对象,......)代表我们的结构域模型.他们知道如何做事,做出决策,保护业务规则,......在这些消息和决策之间,需要有一些东西接收消息并将其转换为域模型.这些是命令处理程序:它们相当愚蠢,它们只是确保消息到达正确的聚合.因此,命令处理程序通常只会从存储库中获取聚合并告诉它执行某些操作,而不了解内部.这巧妙地将命令与域模型分离.

你可能会说我是这种代码组织风格的忠实粉丝.我认为它对DDD非常有用.您可以通过许多其他方式应用DDD.最终,目标不是"做DDD",而是建立解决问题的系统,可测试,可维护和可演化.