<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Vladik Khononov</title>
    <description>The latest articles on DEV Community by Vladik Khononov (@vladikk).</description>
    <link>https://dev.to/vladikk</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F14291%2F12d852b9-e692-42a3-8ad7-dabce4caf0ef.jpg</url>
      <title>DEV Community: Vladik Khononov</title>
      <link>https://dev.to/vladikk</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vladikk"/>
    <language>en</language>
    <item>
      <title>Tackling Complexity in the Heart of Domain-Driven Design</title>
      <dc:creator>Vladik Khononov</dc:creator>
      <pubDate>Wed, 19 Apr 2017 14:50:44 +0000</pubDate>
      <link>https://dev.to/vladikk/tackling-complexity-in-the-heart-of-domain-driven-design</link>
      <guid>https://dev.to/vladikk/tackling-complexity-in-the-heart-of-domain-driven-design</guid>
      <description>&lt;p&gt;Let’s do a little experiment: try to explain the gist of Domain-Driven Design to someone who has no clue about it. This, especially doing it succinctly, is not easy. Heck, I struggle with it myself. Bounded contexts, entities, domain events, value objects, domains, aggregates, repositories… where do you even start?&lt;/p&gt;

&lt;p&gt;To find the order in the apparent chaos, I want to analyze the DDD methodology from a rather unusual perspective — by applying Domain-Driven Design to Domain-Driven Design itself. After all, this methodology is intended to deal with complex domains, isn’t it?&lt;/p&gt;

&lt;p&gt;Let’s start by identifying the core domain: what is DDD’s main competitive advantage, and what are its means of achieving it?&lt;/p&gt;

&lt;h2&gt;
  
  
  The Core Domain: Ubiquitous Language
&lt;/h2&gt;

&lt;p&gt;In "Domain-Driven Design: Tackling Complexity in the Heart of Software"(the Blue Book), Eric Evans argues that poor collaboration between domain experts and software development teams causes many development endeavors to fail. DDD aims to increase the success rates by bridging this collaboration and communication gap. &lt;/p&gt;

&lt;p&gt;To allow fluent sharing of knowledge, DDD calls for cultivation of a shared, business-oriented language: Ubiquitous Language. This language should resemble the business domain and its terms, entities, and processes. &lt;/p&gt;

&lt;p&gt;The Ubiquitous Language should be extensively used throughout the project. All communication should be done in the Ubiquitous Language. All documentation should be formulated in it. Even the code should "speak" the Ubiquitous Language.&lt;/p&gt;

&lt;p&gt;Many methodologies strive to reduce risk and increase success rates of software projects, but since Ubiquitous Language is DDD’s means of achieving it, I consider it as the Core Domain of Domain-Driven Design.&lt;/p&gt;

&lt;p&gt;Defining a Ubiquitous Language is not a trivial thing to do. Since software doesn't cope well with ambiguity, each Ubiquitous Language term should have exactly one meaning. Unfortunately, that's not how human languages work — often words have different meanings in different contexts. To overcome this hurdle and support the process of cultivating a rigorous language, another DDD pattern is employed: Bounded Context.&lt;/p&gt;

&lt;h2&gt;
  
  
  Supporting Sub-Domain: Bounded Contexts
&lt;/h2&gt;

&lt;p&gt;To prevent terms from having multiple meanings, DDD requires each language to have a strict applicability context, called Bounded Context. This pattern defines a boundary, inside of which the Ubiquitous Language can be used freely. Outside of it, the language’s terms may have different meanings.&lt;/p&gt;

&lt;p&gt;Although the Bounded Context pattern is an essential part of Domain-Driven Design, I consider it a Supporting Sub-Domain, since its purpose is to support the formation of a Ubiquitous Language, the Core Domain.&lt;/p&gt;

&lt;p&gt;As I mentioned earlier, the code should also "speak" the Ubiquitous Language of the Bounded Context in which it is implemented. But how do you implement a business domain in code? There is no one-size-fits-all pattern for implementing a business domain. Multiple options are available, and that's our next stop. Be warned: sacred cows are about to be hurt...&lt;/p&gt;

&lt;h2&gt;
  
  
  Generic Sub-Domain: Domain Implementation
&lt;/h2&gt;

&lt;p&gt;These patterns provide different ways of implementing the business domain's logic:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Transaction Script&lt;/li&gt;
&lt;li&gt;Active Record&lt;/li&gt;
&lt;li&gt;Domain Model&lt;/li&gt;
&lt;li&gt;Event-Sourced Domain Model&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Each of these patterns suits a different level of domain complexity. The pattern you choose should be expressive enough to reify the Ubiquitous Language in code. It is crucial to point out that this decision is not set in stone. As the business evolves and the Ubiquitous Language's complexity grows, the implementation pattern can be upgraded to a more elaborate one.&lt;/p&gt;

&lt;p&gt;The aforementioned four patterns of business-domain implementation are the ones I am currently familiar with.&lt;/p&gt;

&lt;p&gt;Indeed, there are may be others than I am currently unaware of.&lt;/p&gt;

&lt;p&gt;New ones may be invented in the future.&lt;/p&gt;

&lt;p&gt;Their implementation differs greatly in various programming paradigms.&lt;/p&gt;

&lt;p&gt;Some best fit a certain programming paradigm but are complex to implement in others.&lt;/p&gt;

&lt;p&gt;With all this volatility in mind, are they an essential part of Domain-Driven Design?&lt;/p&gt;

&lt;p&gt;Since the Domain-Driven Design methodology cannot encompass all business domain implementation patterns, this know-how can, and should, be borrowed from other sources. For example, the Transaction Script, Active Record, and even Domain Model are described in Martin Fowler’s "Patterns of Enterprise Application Architecture" book. By definition, the ability to rely on "off-the-shelf" solutions makes them a Generic Sub-Domain. Yes, even the Domain Model pattern.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implications
&lt;/h2&gt;

&lt;p&gt;The decoupling of Domain-Driven Design from the tactical modeling patterns can have positive, far-reaching implications on DDD's accessibility and adoption rates. I want to elaborate on three of them: reducing DDD's complexity, widening its applicability, and the ability to gain a lot of traction by jumping on the Microservices bandwagon. &lt;/p&gt;

&lt;h3&gt;
  
  
  1. Reduced Complexity
&lt;/h3&gt;

&lt;p&gt;This mind map by Eric Evans depicts the patterns that constitute the Domain-Driven Design methodology:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fvladikk.com%2Fimages%2Fddd%2Fddd-patterns.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fvladikk.com%2Fimages%2Fddd%2Fddd-patterns.png" alt="Domain-Driven Design Patterns"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And this is how it will look if we drop the tactical modeling patterns:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fvladikk.com%2Fimages%2Fddd%2Fddd-patterns2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fvladikk.com%2Fimages%2Fddd%2Fddd-patterns2.png" alt="Domain-Driven Design Patterns"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Shabang! Which one do you think will be easier to grasp and explain?&lt;/p&gt;

&lt;p&gt;Decoupling of DDD from the Tactical Modeling patterns will prevent many of the misconceptions and difficulties many newcomers experience – for example, reading the first four chapters of the Blue Book and having a feeling that they've got a strong grasp of DDD. And speaking of the Blue Book, many complain that it doesn't provide enough code samples. Well, guess what? Once DDD is decoupled from the Tactical Modeling patterns, it no longer requires any code samples at all. It's a pure system modeling methodology that can be applied in any technology stack and any software paradigm.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Wider Applicability
&lt;/h3&gt;

&lt;p&gt;I strongly disagree with the notion that Domain-Driven Design should be applied to complex projects only. This notion is driven by the strong coupling of DDD to the Domain Model pattern. Once we break this coupling, a whole new world of possibilities opens up.&lt;/p&gt;

&lt;h4&gt;
  
  
  Communication
&lt;/h4&gt;

&lt;p&gt;No matter how simple the business domain is, if team members use different terminology for the same artifacts, sooner or later they will find themselves in the realm of accidental complexity. The Ubiquitous Language pattern prevents this scenario and yields a clear communication medium between all team members.&lt;/p&gt;

&lt;h4&gt;
  
  
  Business Growth
&lt;/h4&gt;

&lt;p&gt;A domain's complexity increases more often than it decreases. This possibility of increase is highest for the so-called not complex projects. Once this happens, the implementation pattern decision should be rethought and adapted to the new complexity levels.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Microservices
&lt;/h3&gt;

&lt;p&gt;Microservices are red hot nowadays. Widening the applicability of DDD to more project types will allow many microservices-based solutions to harness the invaluable DDD tools. The Bounded Context pattern provides a business-driven way of dividing a system into a set of independent services, and the Structure Map is a great way to map the services’ topology and interaction patterns between them.&lt;/p&gt;

&lt;h2&gt;
  
  
  "Are You Nuts?"
&lt;/h2&gt;

&lt;p&gt;That's what you're probably thinking right now. However, I don't think that my proposition – to take the Tactical Patterns out of DDD – is as crazy as it initially sounds. Back at the DDD Europe 2016 conference, Eric Evans himself stated that the Domain Model implementation described in the Blue Book was intended to be &lt;em&gt;a&lt;/em&gt; way of implementing a &lt;em&gt;Domain Model&lt;/em&gt;, but many mistook it as &lt;em&gt;the&lt;/em&gt; way of implementing &lt;em&gt;Domain-Driven Design&lt;/em&gt;. See, the Tactical Modeling patterns were never intended to be the one-and-only way to do DDD, but many consider them as such. They produce extraneous noise and detract attention away from the most important, and unique-to-DDD material.&lt;/p&gt;

&lt;p&gt;Also, you cannot say that the Domain-Driven Design methodology is in its perfect state, and has no reason to change. Unfortunately, its low adoption rates speak for themselves. DDD deserves way more attention than it gets. The Blue Book came out more than a decade ago, and since then the methodology has barely changed. I believe that it should change. Not because it's bad – on the contrary, because it's great. But it has much, much more potential than it has currently realized.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final Thoughts
&lt;/h2&gt;

&lt;p&gt;In no way did I intend to denigrate the importance of Tactical Modeling. Quite the opposite: this subject deserves much more attention than it gets. But in its own context. There are many more patterns besides the Domain Model, and more ways to implement them, than can fit in a single DDD book. Moreover, these patterns can be implemented even on non-DDD projects, and a project can follow the DDD principles even if it doesn't have a single aggregate in it.&lt;/p&gt;

&lt;h2&gt;
  
  
  What do you think?
&lt;/h2&gt;

&lt;p&gt;I'd love to hear your opinion on this in the comments. &lt;/p&gt;




&lt;p&gt;&lt;em&gt;This post was originally published on &lt;a href="http://vladikk.com/2016/04/05/tackling-complexity-ddd/" rel="noopener noreferrer"&gt;vladikk.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>domaindrivendesign</category>
      <category>eventsourcing</category>
      <category>cqrs</category>
    </item>
    <item>
      <title>Tackling Complexity in CQRS</title>
      <dc:creator>Vladik Khononov</dc:creator>
      <pubDate>Sun, 16 Apr 2017 11:24:35 +0000</pubDate>
      <link>https://dev.to/vladikk/tackling-complexity-in-cqrs</link>
      <guid>https://dev.to/vladikk/tackling-complexity-in-cqrs</guid>
      <description>&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fvladikk.com%2Fimages%2Fcqrs%2Ftitle-img.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fvladikk.com%2Fimages%2Fcqrs%2Ftitle-img.jpg" alt="Tackling Complexity in CQRS"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The CQRS pattern can do wonders: it can maximize scalability, performance, security, and even &lt;a href="http://codebetter.com/gregyoung/2010/02/20/cqrs-and-cap-theorem/" rel="noopener noreferrer"&gt;“beat” the CAP theorem&lt;/a&gt;. Nonetheless, CQRS has acquired a controversial name because of the complexity it introduces. For instance, &lt;a href="https://martinfowler.com/bliki/CQRS.html" rel="noopener noreferrer"&gt;in his article on CQRS&lt;/a&gt;, Martin Fowler argues that the pattern should be applied sparingly and even cautiously:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;“… for most systems CQRS adds risky complexity”&lt;/li&gt;
&lt;li&gt;“… you should be very cautious about using CQRS”&lt;/li&gt;
&lt;li&gt;“So while CQRS is a pattern that's good to have in the toolbox, beware that it is difficult to use well and you can easily chop off important bits if you mishandle it.”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;From my point of view, the CQRS-induced complexity is largely accidental, and thus can be avoided. To illustrate my point, I want to discuss the goal of CQRS, and then analyze 3 common sources of accidental complexity in CQRS-based systems.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Goal of CQRS
&lt;/h2&gt;

&lt;p&gt;The goal of CQRS is to enable representation of the same data using multiple models. Not scalability, not availability, not security, not performance. Same data in multiple models. That's it. The rest is byproducts. Don't believe me? Listen to &lt;a href="https://youtu.be/LDW0QWie21s?t=448" rel="noopener noreferrer"&gt;Greg Young's talk at the DDDEU2016 conference&lt;/a&gt;, where he says that CQRS was invented to support implementation of Event Sourcing. And, as you probably know, the Event Sourcing model is awesome for writing data, but terrible for reading. That's why he needed CQRS back then: &lt;em&gt;to represent the same data in multiple models&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;How does CQRS achieve this goal? By making sure that only one model serves as the source of truth, and all changes are committed to this model only.&lt;/p&gt;

&lt;p&gt;Let’s see how this understanding can help us tackle some complexities.&lt;/p&gt;

&lt;h2&gt;
  
  
  Complexity Trap #1: One-Way Commands, or Overzealous Segregation
&lt;/h2&gt;

&lt;p&gt;All definitions of CQRS that I'm aware of follow this pattern:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;CQRS is based on the CQS principle, which states that operations should be divided into two groups: commands that change data, and queries that return data. Once we elevate this principle to the architectural level, we get a system with use cases segregated into same two groups: commands and queries. Each use case can be either command or query, but never both.&lt;/li&gt;
&lt;li&gt;Once the use cases are segregated, we get quite a few benefits: multiple models, different persistence mechanisms, independent scalability, etc. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Do you sense something wrong here? The issue is subtle: all definitions of CQRS usually start with the solution – the segregation, and only afterwards define the problem – multiple models. This causes too much zeal about the segregation: going as far as to define commands as one-way, where you get Ack/Nack response from the server, but have to poll some read model store for the actual command execution result. In other words, complexity hell unleashed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution: Relax the Segregation
&lt;/h3&gt;

&lt;p&gt;Let’s take a step back and reconsider the segregation. We’ve seen that, according to CQRS, to represent the same data in multiple models, a use case can either write or read data. It’s a no-brainer that a read model shouldn’t update anything, since otherwise we’d end up with multiple sources of truth. But should you really keep your commands void?&lt;/p&gt;

&lt;p&gt;Not really. Without violating any principles, a command can safely return the following data:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Execution result - success / failure;&lt;/li&gt;
&lt;li&gt;Error messages or validation errors, in case of a failure;&lt;/li&gt;
&lt;li&gt;The aggregate’s new version number, in case of success;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This information will dramatically improve the user experience of your system, because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;you don’t have to poll an external source for command execution result, you have it right away. It becomes trivial to validate commands, and to return error messages; and&lt;/li&gt;
&lt;li&gt;if you want to refresh the displayed data, you can use the aggregate’s new version to determine whether the view model reflects the executed command or not. No more displaying stale data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Speaking of data, can we relax the segregation a bit more? In many cases, any data contained &lt;em&gt;inside&lt;/em&gt; the affected aggregate can be returned as part of the command execution result. However, there is a slight nuance here: make sure that the returned data can be queried later on from one of the read models. Otherwise there is a slight risk that the data might be lost, in case the response doesn't make its way to the client.&lt;/p&gt;

&lt;p&gt;You can see an example of such approach in &lt;a href="http://danielwhittaker.me/2016/04/20/how-to-validate-commands-in-a-cqrs-application/" rel="noopener noreferrer"&gt;Daniel Whittaker's blog&lt;/a&gt;, where he discusses the usage of command execution objects for validation of commands.&lt;/p&gt;

&lt;p&gt;Also, in this &lt;a href="https://gist.github.com/vladikk/86da55d0eb09d7a291b9f9a5b406f2c9" rel="noopener noreferrer"&gt;gist&lt;/a&gt; you can see the command execution result object that I use in C#. &lt;/p&gt;

&lt;h2&gt;
  
  
  Complexity Trap #2: Event sourcing
&lt;/h2&gt;

&lt;p&gt;For historical reasons, CQRS is closely associated with the Event Sourcing pattern. After all, CQRS was invented to make Event Sourcing possible. But let’s reevaluate the coupling between the two patterns.&lt;/p&gt;

&lt;p&gt;As I’ve said before, the goal of CQRS is to allow representation of the same data in different models. If you’re working with an Event Sourced Domain Model, you absolutely need CQRS to be able to execute queries. However, there are lots of other perfectly valid reasons to implement CQRS that are not related to Event Sourcing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your system should display its entities in different representation models.&lt;/li&gt;
&lt;li&gt;You have to support different querying models (search, graph, documents, etc.).&lt;/li&gt;
&lt;li&gt;The difference between writes and reads differs greatly, and you want to scale them independently.&lt;/li&gt;
&lt;li&gt;You hate O/RMs.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Does this mean that in all these cases you have to go down the Event Sourcing route? If you do, you’re deep in a complexity trap. Event Sourcing is a way of modeling business domains. Not just a way, but probably the most complex way. Therefore, you should employ Event Sourcing if, and only if, your business domain justifies it. Let's see how you can implement CQRS in other cases.&lt;/p&gt;

&lt;h3&gt;
  
  
  Solution: CQRS != Event Sourcing
&lt;/h3&gt;

&lt;p&gt;We’ve been taught to generate projections by writing handlers for events. But how do you implement projections without events? There is another way to do projections, and I call it “State Based Projections”. This topic merits a post of its own, but I’ll briefly describe three ways to implement “State Based Projections”:&lt;/p&gt;

&lt;h4&gt;
  
  
  1. “Is Dirty” Flag
&lt;/h4&gt;

&lt;p&gt;You can mark an entity that was updated by raising the IsDirty flag, and implement a projection engine that will query for dirty instances and project the updated data into distinct models. To rebuild projections, you just have to raise the flag back for all records.&lt;/p&gt;

&lt;h4&gt;
  
  
  2. Catch-Up
&lt;/h4&gt;

&lt;p&gt;In relational databases, you can track commits at the table level. For example, in SQL Server you have a built-in mechanism for that, the &lt;a href="https://msdn.microsoft.com/en-us/library/ms182776.aspx" rel="noopener noreferrer"&gt;“rowversion” column&lt;/a&gt;. Such functionality can be implemented for other relational databases as well. A projection engine will query updated rows in a catch-up-subscription-like way, and project the updated data. To rebuild a projection from scratch, you have to "rollback" the last known commit id back to 0.&lt;/p&gt;

&lt;h4&gt;
  
  
  3. Database Views
&lt;/h4&gt;

&lt;p&gt;If you use a relational database, and all you need is to represent its data in different models, database views will work great. Yep, a perfectly valid CQRS system can be implemented in the database. Probably the least sexiest solution - but not only does it work, it also naturally follows the CQRS pattern.&lt;/p&gt;

&lt;p&gt;These ways to project models may not be cool and sexy, but they work. I’ve seen quite a few projects that have employed them, and they worked like a charm, without unjustifiably drowning in Event Sourcing related complexity.&lt;/p&gt;

&lt;p&gt;Wait, did I just suggest to ignore Event Sourcing at all costs because it is complex? Hell no! Event Sourcing is one of the most important tools in  your toolbox. But as any tool, use it in its context - business domains that bring business value: Core Subdomains. On the other hand, Generic and Supporting subdomains, that are simple enough to be implemented with Transaction Script or Active Record patterns, can still benefit from CQRS. In such case, employ the simplest tool that will do the job, and rip the benefits of CQRS using State Based Projections.&lt;/p&gt;

&lt;h2&gt;
  
  
  Complexity Trap #3: Too Much of a Good Thing
&lt;/h2&gt;

&lt;p&gt;The Microservices hype has attracted lots of attention to CQRS: if you have a set of independent services that need to query each other’s data, &lt;a href="https://www.ibm.com/developerworks/cloud/library/cl-build-app-using-microservices-and-cqrs-trs/" rel="noopener noreferrer"&gt;CQRS is the common solution&lt;/a&gt;. However, I’ve seen this approach produce monstrous data flow diagrams of services projecting lots of data between them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fvladikk.com%2Fimages%2Fcqrs%2Fmicroservices.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fvladikk.com%2Fimages%2Fcqrs%2Fmicroservices.jpg" alt="Fine grained microservices"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is not always bad, but in many cases it might be a signal to take step back and reconsider your decomposition strategy. Chances are that your services are too fine-grained and do not reflect the business domain’s boundaries. If this is the case, you can greatly reduce your architecture’s complexity by realigning services boundaries with their corresponding business domains.&lt;/p&gt;

&lt;h2&gt;
  
  
  CQRS: Decomplexified
&lt;/h2&gt;

&lt;p&gt;I want to sum it all up with a diagram of CQRS:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fvladikk.com%2Fimages%2Fcqrs%2Fcqrs-diagram.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fvladikk.com%2Fimages%2Fcqrs%2Fcqrs-diagram.png" alt="CQRS diagram"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This diagram differs from other diagrams you can find on the web:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fvladikk.com%2Fimages%2Fcqrs%2Fgoogle-cqrs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/http%3A%2F%2Fvladikk.com%2Fimages%2Fcqrs%2Fgoogle-cqrs.png" alt="Other CQRS diagrams"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is the CQRS pattern the way I both see and implement it. Commands have responses. The projection mechanism defined is abstractly without any implementation details. Inside it may be based on events, or on state, or even a database view. And finally, there  is no glimpse of Event Sourcing. Model the system’s business logic as required by the business domain: Active Record, Domain Model, or Event Sourced Domain Model.&lt;/p&gt;

&lt;p&gt;As with every correctly applied tool, CQRS should reduce complexity, not induce it. If your architecture’s complexity grows, you’re doing something wrong.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;This post was originally published on &lt;a href="http://vladikk.com/2017/03/20/tackling-complexity-in-cqrs/" rel="noopener noreferrer"&gt;vladikk.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
      <category>cqrs</category>
      <category>eventsourcing</category>
      <category>domaindrivendesign</category>
    </item>
  </channel>
</rss>
