`
oojdon
  • 浏览: 40609 次
  • 性别: Icon_minigender_1
社区版块
存档分类
最新评论

DDD设计,为什么我热爱CQRS

阅读更多

地址是:http://jonathan-oliver.blogspot.com/2009/10/dddd-why-i-love-cqrs.html

[UPDATE: This post was written about the time Greg Young formally named his CQS architectural implementation of command query separation.  Because of the change in terminology this post was written with the understanding that CQRS consisted of all elements commonly associated with CQRS.  In other words, CQRS herein is incorrectly defined as the following concepts together: DDD, event sourcing, domain events, true “CQRS”, and eventual consistency.  It should be noted that all of those concepts better fit under the umbrella of “DDDD” or Distributed Domain-Driven Design.  In Greg Young’s recent blog posts he clarifies what CQRS is and is not.]

There are a number of significant advantages to using an emerging pattern known as Command Query Responsibility Segregation (CQRS), formally known as Command Query Separation [Young].

vs. ActiveRecord

ActiveRecord is an incredibly quick and powerful way to create an application to deliver business value as evidenced by the abrupt emergence and fast-growing popularity of Ruby on Rails. Specifically, its power revolves around displaying and mutating objects matching a database schema, thus avoiding such technical complexity as the impedance mismatch problem.

A critical deficiency to ActiveRecord is when business logic reaches a certain level of complexity. Once at that point, ActiveRecord begins to “break down” and it becomes difficult to ensure that all business logic is properly maintained in a single location and handled in a consistent fashion.

Furthermore, all business state is governed by the database. In other words, the database becomes the single point of failure and performance bottleneck. Possible resolutions might include sharding the database but referential integrity and distributed transactions could become an issue. These could be abandoned but that would require more technical complexity to ensure consistent application state. Further, reconstructing a report or screen would then require retrieval of data from disparate sources.

vs. Traditional Domain Model

Domain-Driven Design should be used when business complexity merits the overhead and difficulty of discovering the correct domain model. Otherwise, ActiveRecord or another type of pattern should be used. Even so, DDD has the advantage of isolating all business logic into a single location. Even with "anemic" domain models the logic is still in one place.

A significant downside of traditional DDD is found in the common practice of using an object-relational mapper or similar data access strategy. Specifically, the domain objects may not necessarily be truly “POCO” or “POJO”. For example, in C# you end up having to declare your methods as “virtual” or you may have to create unused, protected constructors. Some ORMs even require you to use a certain base class in order for the ORM to perform its magic.

In addition, many DDDers query their domain objects through a repository for data to display on a report or screen. Many also have their domain objects return a DTO that can be databound to the screen. The problem here is that domain objects are not meant for display—they’re behavioral entities--they have behavior rather than shape. This often results in additional properties on domain model entities to support information needed on a particular report or screen. Lastly, because the domain object is now used for display, there is an extra level of coupling that must be addressed when refactoring domain objects.

CQRS: A Class By Itself

The CQRS style of programming isolates domain complexity into a particular location like its traditional DDD counterpart, but it doesn’t expose state—only behavior through methods that can be invoked and that return "void". In this way, the domain model is strictly behavioral and can more easily be refactored towards deeper insight.

There are a number of significant, positive consequences when using CQRS that you don’t get by default with the aforementioned patterns.

  1. Distributed systems capabilities: CQRS facilitates spreading your application across multiple physical machines using messaging patterns.
  2. High availability: Because the application is distributed, each piece can continue to function in the absence or failure of any other piece. Further, the distributed nature has a “load leveling” effect whereby spikes in demand are leveled using messaging.
  3. External systems integration: Messaging patterns  facilitate the ability to easily replicate both the intent as well as the data of domain events to external systems.
  4. NoSQL: CQRS doesn’t even require a database to support the domain model. It only needs a relational database if you choose to use one for reporting. This prevents the reporting database from being a single point of failure or even a bottleneck because it can be scaled independently from the rest of the application.
  5. Auditing and historical tracing: I’ve done a lot of work with temporal databases in an attempt to have a complete and accurate audit. (That’s what attracted me to this pattern in the first place.) The problem with temporal DBs and schemas is that the technical complexity quickly overwhelms the business complexity as the two become easily mixed. In CQRS, we capture each state transition explicitly which gives us a complete and accurate historical record that we can fast forward or rewind to any point in time.
  6. One repository: There has been some debate over the last few months about theviability of the repository pattern. The argument is that a repository cannot handle all of the querying needs of the application. This is absolutely, 100% correct, which is why we should only use the repository in the domain model to query by ID in order to get a single domain object back. When we need data for a particular screen or report we should use the correct tool for the job and go straight to the database. This is what databases are designed for and CQRS appropriately pushes us in that direction.
  7. Screen-based reporting: Rather than trying to bind domain objects to the screen, CQRS tells us to query the database directly and to have simple DTOs which are screen-based objects. This allows us to query all the information necessary for a particular screen in a single request rather than 3, 4, 5, or even 15 DB requests per screen. This also makes development using MVC patterns significantly easier.

Conclusion

While reading technical blog posts or listening to technical podcasts, I am constantly amazed at how elegantly and beautifully CQRS solves a multitude of deficiencies found in more established or “more traditional” approaches.

分享到:
评论

相关推荐

    DDDSample-CQRS.rar_CQRS eventhandler_cqrs_ddd示例代码_领域驱动cqrs

    事件存储在CQRS+DDD中扮演着关键角色,因为它为系统提供了重构和回溯的可能性。 总的来说,"DDDSample-CQRS"示例展示了如何在实践中融合DDD和CQRS,利用Nhibernate进行数据持久化,构建出一个高度解耦、易于维护和...

    大白话领域驱动设计DDD视频教程

    DDD领域驱动设计到底是什么? DDD和传统三层优劣势比较 DDD在国内现象是个什么情况? DDD从战略设计到战术设计概览 第2章 领域分析模型 核心域,支撑子域,通用子域 微服务和DDD是什么关系? 传统模式下如何合理的...

    dotnet-一个基于DDD领域驱动设计CQRS命令查询职责分离的netcore框架

    《基于DDD领域驱动设计与CQRS命令查询职责分离的.NET Core框架详解》 在软件开发领域,领域驱动设计(Domain-Driven Design,简称DDD)和CQRS(Command Query Responsibility Segregation,命令查询职责分离)是两...

    DDD中的那些模式—CQRS

    DDD作为一种系统分析的方法论,最大的问题是如何在项目中实践。而在实践过程中必然会面临许多的问题,「模式」是系统架构领域中一种常见的...CQRS,中文名为命令查询职责分离。 毋庸置疑「领域」在DDD中占据了核心的地

    CQRS介绍 CQRS概述

    CQRS(Command Query Responsibility ...和上面第一种做法相比,我想不到什么好处。而采用ES,则所有C端的最新数据全部用Domain Event表达即可;而要查询显示用的数据,则从Q端的ReadDB(关系型数据库)查询即可。

    遵循 Clean、DDD、Saga、CQRS 和六边形架构设计模式的食品订购系统.zip

    《基于Clean、DDD、Saga、CQRS和六边形架构设计模式的食品订购系统解析》 在现代软件开发中,采用先进的设计模式和技术是确保系统灵活性、可维护性和扩展性的关键。本篇文章将深入探讨一个遵循Clean、领域驱动设计...

    CQRS架构实例

    在CQRS中,应用通常被划分为多个层次,如表示层、应用服务层、领域层和基础设施层。各层之间的职责分明,确保了代码的清晰和模块化。 6. **微服务** CQRS与微服务架构相结合,可以使每个服务独立处理其自己的读写...

    magic-bottle项目是一套匿名社交系统,包括Andriod、WEB管理端以及服务端,采用DDD+CQRS架构

    magic-bottle项目是一套匿名社交系统,包括Andriod、WEB管理端以及服务端,采用DDD+CQRS架构 magic-bottle项目是一套匿名社交系统,包括Andriod、WEB管理端以及服务端,采用DDD+CQRS架构 magic-bottle项目是一套...

    ddd-cqrs-cqrs-es:该演示项目介绍了如何根据DDD,CQRS,CQRS-ES模型分析和设计软件

    《基于DDD、CQRS与事件溯源的软件设计实践——ddd-cqrs-cqrs-es项目解析》 在软件开发领域,领域驱动设计(Domain-Driven Design,简称DDD)、命令查询职责分离(Command Query Responsibility Segregation,简称...

    java-ddd-example:using使用SpringBoot的Java项目中的六角结构+ DDD + CQRS

    遵循域驱动设计(DDD)和命令查询责任隔离(CQRS)原则的Java应用程序的实现示例,以使代码尽可能简单。 看看,玩,玩得开心! :rocket: 环境设定 安装Java: brew cask install java 克隆此存储库: git clone ...

    读书笔记:基于.net 5 的微服务开发框架,使用简化的DDD+CQRS设计.zip

    读书笔记:基于.net 5 的微服务开发框架,使用简化的DDD+CQRS设计

    CQRS 探索之旅

    CQRS 旅程CQRS 旅程CQRS 旅程CQRS 旅程CQRS 旅程CQRS 旅程

    Xer.Cqrs:轻巧易用的CQRS + DDD库

    什么是Xer.Cqrs? Xer.Cqrs是一个便捷程序包,其中包含构建具有DDD概念的CQRS写面所需的所有程序包。 它将其他轻量级XerProjects库分组在一起: -包含域驱动设计(DDD)组件/概念。 -包含用于处理命令的组件。 -...

    banksimplistic, 利用 ruby 开发 CQRS 事件源和 DDD.zip

    banksimplistic, 利用 ruby 开发 CQRS 事件源和 DDD BankSimplisticBankSimplistic是一个沙箱,用于探索命令查询职责隔离( CQRS ) 。事件来源和域驱动的设计( DDD ) ( 带有 ruby ) 。系统基于 nijhof Fohjin的标记 ...

    CQRS读写分离模式的例子

    3. **领域驱动设计(DDD)**:CQRS与DDD结合,能更好地反映领域模型的业务规则,使系统更符合领域专家的理解。 **CQRS的基本架构** CQRS架构通常包含以下组件: 1. **写模型(Write Model)**:负责处理所有对...

    php-ddd-example:using使用Symfony 5在PHP中使用六角结构+ DDD + CQRS

    :elephant: :direct_hit: 六边形架构,PHP中的DDD和CQRS 使用域驱动设计(DDD)和命令查询责任隔离(CQRS)原理的PHP应用程序示例,使代码尽可能简单。 看看,玩,玩得开心。 ·· :rocket: 环境设定 :spouting_...

    CQRS_DDD:CQRS和DDD架构模式

    CQRS和DDD架构模式抽象的这项工作提出了CQRS(命令和查询责任隔离)和DDD(域驱动设计)体系结构模式的实际应用,其中包括: 领域模型和有界上下文定义技术代码和业务逻辑之间的清晰分离指令端休息API 查询侧边api ...

    Pos:由DERMAYON LIBRARY提供支持的示例应用程序DDD,React式微服务,CQRS事件源

    POS-DDD,React式微服务,CQRS事件源由DERMAYON LIBRARY提供支持具有CQRS的DDD响应式微服务和带有事件源的示例应用程序。建筑学特征微服务CQRS(命令查询职责隔离) 活动采购通用存储库工作单位域驱动设计Api ...

    基于 DDD、EventSourcing 的现代响应式 CQRS 架构微服务开发框架

    在现代软件开发中,复杂性日益增长,为了应对这一挑战,一种先进的架构模式应运而生,那就是基于领域驱动设计(DDD)、事件溯源(Event Sourcing)和命令查询职责分离(CQRS)的响应式微服务开发框架。本文将深入...

Global site tag (gtag.js) - Google Analytics