Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Domain driven design concepts and relation with CQRS

I recently started to become familiar with DDD concepts and CQRS and I realized that one of the most important concepts in CQRS is DDD beside load balancing, NServiceBus and etc but I am curious if we can use DDD concept alone without using it in CQRS complexity for developing and creating our project. As I know it is an approach to software development for complex needs by connecting the implementation to an evolving model.I need to know that how much should be the scale of project to use DDD alone or with CQRS.

like image 601
sajadre Avatar asked Apr 19 '19 08:04

sajadre


People also ask

Is CQRS Domain-Driven Design?

The short answer is: Yes, you can. CQRS as an architectural style came after DDD. It's based on the Command-Query Separation (CQS).

How is Domain-Driven Design related to microservices?

Microservices have a symbiotic relationship with domain-driven design (DDD)—a design approach where the business domain is carefully modeled in software and evolved over time, independently of the plumbing that makes the system work.

Are CQRS commands part of the domain model?

CQRS commands and the onion architectureCommands belong to the core domain (just like domain events). They play an important role in the CQRS architecture - they explicitly represent what the clients can do with the application. Just like events represent what the outcome of those actions could be.

What is DDD in microservices and why it is required?

Initially coined by Eric Evans, Domain-Driven Design (DDD) is defined as designing software systems based on the underlying model of the business domain. Domain-Driven Design has an organizational relationship to microservices and categorizes them so their usage is easily understood.


3 Answers

As a complement of @expandable's answer:

CQRS, aggregates, event sourcing, etc. are just tools. Experience shown that they work well in DDD projects. Using these tools does not mean that you do DDD.

DDD is about distilling an ubiquitous language through conversations between developers and domain experts. During these discussions, you will notice that some word have different meaning depending of the context.

For instance, you can think about the life cycle of a product for an online retail store (like Amazon). After the discussion with the domain experts you may find that the Product have a different meaning depending on the life cycle of the purchase. For the retail context, a product is about price and description whereas in the shipping context what matters is the destination address and the size and weight of the product.

This is a clue that two languages are used and that you probably have to create a bounded context for each (retail and shipping). A bounded context represent an area of the domain in which one language is used. The context boundaries appears when the meaning of the words of the language start to change.

The bounded contexts identified after the discuss between developers and the domain experts need to be aligned with the code base. For this example, you would probably create a package for retail and another one for shipping. Bounded context implementation is usually quite decoupled one from another. For instance, each bounded context would have it own product class with different properties.

Each bounded can have it own architecture: CQRS, Event Sourcing, Hexagonal, etc. depending on the needs. However you should be careful that the architecture that you choose is well aligned with the bounded context's domain. For instance, you would probably not use event sourcing if your domain is not event based itself.

like image 192
Dnomyar Avatar answered Oct 12 '22 11:10

Dnomyar


The short answer is: Yes, you can.

CQRS as an architectural style came after DDD. It's based on the Command-Query Separation (CQS).

As a pattern CQRS can be used to optimize your application. If you need to show a lot of data to the user from multiple Aggregates at the same time, you may need to make a lot of database queries to get this data. This can become inefficient. Here are some options you can choose (not a complete list of course):

  • Option 1: Compromise you Domain Model to satisfy that need and make it more suitable for reading.

  • Option 2: Completely separate the two like CQRS does. Keep a write model that is nice and represents your domain and at the same time have a read model that represent how you want your data to be displayed to the user.

  • Option 3 Design your User Interface/Front End to not show all the data at the same time. For example take the way that UI's in phones work. Since they have smaller screens, slower CPU's and less RAM and the most important thing: battery that dies all the time, they will usually show a small portion of the data and then you have navigate to see more. Make one request after the other instead of having a huge one and show everything in one screen. You can contrast this with desktop applications that have rich menus an show you a lot of stuff when you open them.

This does introduce additional complexity that you may not want to manage, so you may choose option 1 or 3 depending on your organization (making people design UI in this way can be tricky, so you may go for option 1 as a compromise).

From my experience, unless you are developing an application that will process data from a lot of users (say 200 000 and even then it may be fine) you may skip the CQRS. If you have this problem later you can always refactor to it. Having a single nice Domain Model makes it easier to later introduce CQRS.

If you haven't read the DDD book, I strongly recommend it.

Here is a great article for CQRS. It discusses how most people think that you have to use separate databases of make the propagation from write to read side asynchronous.

It's quite OK to have a single database for the two models and make the propagation synchronous. You can even make the updates of the read model in the same transaction if you are using a transactional database to avoid having eventual consistency. This will reduce the complexity, but may introduce additional delays if your write side also has heavy load on it. If this is the case you can go with asynchronous eventually consistent solution and deal with the consequences from it.

Apply some initial analysis and see if CQRS will bring any value. If it does start with it. If it doesn't, start without it. If your new to both DDD and CQRS, it's better not to start with both of them in the same application as you may introduce unexpected complexity and get yourself in difficult situation. Start with DDD, gain experience in it and then you can try CQRS.

like image 38
expandable Avatar answered Oct 12 '22 10:10

expandable


I think that connecting these principles together (DDD, CQRS, Event Sourcing) in many online sources, brought more harm than benefit to DDD itself. Your question is a good example of this, many people think DDD = CQRS + ES (+ microservices sometimes).

In its core, DDD has nothing to do with neither CQRS nor ES, as it is just a design "framework", whereas CQRS and ES are implementation patterns. In other words, when you have DDD hat on, you shouldn't be thinking about CQRS nor ES at all, because you are designing software, not implementing it.

Why CQRS is a good fit for DDD design? The answer is, that it is not :). It is a good implementation pattern for the Event Sourced system, and it turns out, that you can easily create a good Event Sourced system when you designed it following DDD principles (mainly when you've found good Bounded contexts and proper Aggregate Roots).

So the connection point is only between CQRS and ES. Greg Young, the author of the CQRS term, coined it as an introduction to Event Sourcing architecture pattern. It is hard to create an ES system without some sort of CQRS. But DDD is not required at all. Of course, all three work very well together.

Regarding your thoughts that DDD is one of the main concepts in CQRS, you are wrong in my opinion.

Many sources online, explain CQRS as a CQS on steroids, which is completely misleading. The core concept in CQRS is segregation of read and write part of the system, into two - completely separated applications. Write part shouldn't be aware of a read part, whereas read knows every little detail of the write part (including any private/hidden data). DDD has nothing to do with it. As I said earlier, CQRS enables ES that benefits from DDD.

Answering your question about a scale: It depends. A bigger system is more likely to benefit from CQRS, as there will be more features, more views, more users who want to see the system in a different way. I think it more depends on the number and type of users, than the scale of the software. CQRS enables you to create different views on the same data very easy, and this is the main factor, that big software will benefit from.

Regarding DDD and a scale of the project. There is no correlation here. When your software is a CRUD type, don't use DDD at all. Domain design is only for software with a complex domain.

like image 37
berhalak Avatar answered Oct 12 '22 10:10

berhalak