域驱动的设计概念以及与CQRS的关系

问题描述 投票:0回答:2

我最近开始熟悉DDD概念和CQRS,我意识到CQRS中最重要的概念之一是除了负载均衡,NServiceBus等之外的DDD,但我很好奇我们是否可以单独使用DDD概念而不使用它在CQRS复杂性中开发和创建我们的项目。据我所知,这是一种通过将实现连接到不断发展的模型来满足复杂需求的软件开发方法。我需要知道单独使用DDD或使用CQRS的项目规模应该是多少。

domain-driven-design load-balancing nservicebus cqrs
2个回答
4
投票

作为@extensable的答案的补充:

CQRS,聚合,事件采购等只是工具。经验表明,它们在DDD项目中运作良好。使用这些工具并不意味着你做DDD。

DDD是通过开发人员和领域专家之间的对话来提炼无处不在的语言。在这些讨论中,您会注意到某些词根据上下文具有不同的含义。

例如,您可以考虑在线零售商店(如亚马逊)的产品生命周期。在与域专家讨论后,您可能会发现产品具有不同的含义,具体取决于购买的生命周期。对于零售环境,产品是关于价格和描述,而在运输环境中,重要的是目的地地址和产品的尺寸和重量。

这是使用两种语言的线索,您可能需要为每种语言(零售和运输)创建有界上下文。有界上下文表示使用一种语言的域的区域。当语言的含义开始改变时,出现上下文边界。

在开发人员和领域专家讨论之后确定的有限上下文需要与代码库保持一致。对于此示例,您可能会创建一个零售包和另一个用于发货的包。有界上下文实现通常彼此非常分离。例如,每个有界上下文都有自己的具有不同属性的产品类。

每个有界可以拥有自己的架构:CQRS,事件采购,六角形等,具体取决于需求。但是,您应该注意,您选择的体系结构与有界上下文的域完全一致。例如,如果您的域不是基于事件的,那么您可能不会使用事件源。


3
投票

简短的回答是:是的,你可以。

DDRS作为一种建筑风格来自DDD。它基于Command-Query Separation (CQS)

作为模式,CQRS可用于优化您的应用程序。如果您需要同时从多个聚合中向用户显示大量数据,则可能需要进行大量数据库查询才能获取此数据。这可能变得低效。您可以选择以下选项(不是完整的课程列表):

  • 选项1:妥协您的域模型以满足该需求并使其更适合阅读。
  • 选项2:像CQRS那样将两者完全分开。保持一个很好的写模型并代表您的域,同时拥有一个读模型,表示您希望如何将数据显示给用户。
  • 选项3将用户界面/前端设计为不同时显示所有数据。例如,采用手机中UI的工作方式。由于它们具有较小的屏幕,较慢的CPU和较少的RAM以及最重要的事情:电池一直在死,它们通常会显示一小部分数据,然后您可以导航以查看更多信息。一个接一个请求,而不是一个巨大的请求,并在一个屏幕上显示所有内容。您可以将其与具有丰富菜单的桌面应用程序进行对比,在打开它们时向您显示很多内容。

这确实引入了您可能不想管理的额外复杂性,因此您可以根据您的组织选择选项1或3(使人们以这种方式设计UI可能会非常棘手,因此您可以选择选项1作为折衷方案)。

根据我的经验,除非您正在开发一个处理来自大量用户的数据的应用程序(比如20万,甚至可能没问题),否则您可以跳过CQRS。如果您以后遇到此问题,可以随时重构。拥有一个不错的域模型可以让以后更容易引入CQRS。

如果你还没有读过DDD book,我强烈推荐它。

Here is a great article for CQRS。它讨论了大多数人认为你必须使用单独的数据库使得从写入到读取端的传播异步。

为两个模型建立单个数据库并使传播同步是完全可以的。如果您使用事务数据库以避免最终的一致性,您甚至可以在同一事务中更新读取模型。这将降低复杂性,但如果您的写入方面也有很多负载,可能会引入额外的延迟。如果是这种情况,您可以使用异步最终一致的解决方案并处理其后果。

应用一些初步分析,看看CQRS是否会带来任何价值。如果它确实从它开始。如果没有,请从没有它开始。如果你是DDD和CQRS的新手,最好不要在同一个应用程序中同时启动它们,因为你可能会引入意想不到的复杂性并让自己陷入困境。从DDD开始,获得经验,然后您可以尝试CQRS。

热门问题
推荐问题
最新问题