Review of 'Implementing Domaindriven Design' on 'Storygraph'
5 stars
I got this as a Kindle edition, but there is no Kindle edition, so Hardcover will have to do. EDIT: I bought the hardcover as well as the Kindle edition. I'm going to be using this book LOTS.
This is an incredibly comprehensive and complete book. It takes Eric Evan's "Domain Driven Design" and roughly two hundred different blog posts, example projects and community thinking and tries to condense them into a single book.
As such, it goes over DDD from a "what are we doing" requirements perspective to a very detailed CQRS implementation, complete with event sourcing. It references every single blog post I've ever heard about the subject and many I haven't, and tries to put it in the context of a single company. The sheer amount of work and editing for this book must have been staggering -- even if you know DDD backwards and forwards, accumulating …
I got this as a Kindle edition, but there is no Kindle edition, so Hardcover will have to do. EDIT: I bought the hardcover as well as the Kindle edition. I'm going to be using this book LOTS.
This is an incredibly comprehensive and complete book. It takes Eric Evan's "Domain Driven Design" and roughly two hundred different blog posts, example projects and community thinking and tries to condense them into a single book.
As such, it goes over DDD from a "what are we doing" requirements perspective to a very detailed CQRS implementation, complete with event sourcing. It references every single blog post I've ever heard about the subject and many I haven't, and tries to put it in the context of a single company. The sheer amount of work and editing for this book must have been staggering -- even if you know DDD backwards and forwards, accumulating and presenting that information is not at all easy to do.
Especially for newer topics, this book excels. It goes into detail on specialized cases like using datafabric / grid computing for retrieving the state of event source aggregates, using snapshot events, or using Mule's collection aggregator.
Where it really falls over is the humor. You just can't make mock popular culture radio interviews about DDD funny. Likewise, the two cowboys trading bon-mots falls completely flat.
Still, totally worth it, and I find the other reviews that badmouth this book and then push another book "helpfully linked" to be at best dishonest, if not Complete Bullshit.
Quotes!
Simply stated, practicing DDD-Lite leads to the construction of inferior domain models.
The whole Domain of the organization is composed of Subdomains. Using DDD, models are developed in Bounded Contexts.
When we employ DDD, we strive for each Bounded Context to mark off where the meaning of every term used by the domain model is well understood, or at least should be if we’ve done a good job of modeling the software. It’s chiefly a linguistic boundary. These contextual boundaries are a key to implementing DDD.
For example, the term Customer must have multiple meanings. When a user is browsing the Catalog, Customer means one thing, but when a user is placing an Order, it means something else. Here’s why. When browsing the Catalog, Customer is being used in the context of previous purchases, loyalty, available products, discounts, and shipping options. On the Order itself, however, Customer has a limited meaning. Among the few details there is a name with a ship-to address, a bill-to address, a total due, and payment terms. Just by this basic reasoning we see that in the e-Commerce System there is no one clean meaning for Customer. Given this situation, as we look around that system we would expect to find several other terms that have multiple meanings. It’s not a clean Bounded Context with an explicit meaning for each term naming a domain concept.
CQRS is meant to solve a specific view sophistication problem, not to tack on as a cool new style that will strengthen your résumé.
It’s worth noting that CQRS-based views can be both cheap and disposable (for development and in maintenance). This is especially so if you use a simple form of Event Sourcing (see the section “Event Sourcing” later in the chapter and Appendix A) and save all Events into a persistent store, which can be republished at any time to create new persistent view data. Doing so, any single view could be rewritten from scratch in isolation or the entire query model be switched to completely different persistence technology. This makes it easy to create and maintain views that continuously address ongoing UI needs. This can lead to more intuitive user experiences that avoid the table paradigm but are instead much richer.
Each command is sent as an asynchronous message and delivered to a handler designed with the dedicated style. This not only enables each command processor component to receive specifically typed messages, but processors of a given type can be added to deal with command processing load. This approach should not be used by default, as it has a more complex design.
Unless Event logging is a requirement specified by the business, the command model can be persisted using an object-relational mapper (ORM) to a relational database or some other approach.
We can produce domain models that publish Domain Events without the need to support Event Sourcing. As a persistence mechanism, Event Sourcing replaces and is far different from using an ORM tool. Because Events are often persisted in an Event Store as binary representations, they cannot (optimally) be used for queries. In fact, Repositories designed for an Event Sourcing model require only a single get/find operation, and that method takes as a parameter only the Aggregate unique identity. Further, by design Aggregates don’t have any query methods (getters). As a result, we need another way to query, which generally leads to employing CQRS (discussed previously) hand-in-glove with Event Sourcing.
With MySQL, there is a maximum row width of 65,535 bytes. Again, that’s row width, not column width. If we declare even one column with the maximum VARCHAR column type width of 65,535, there is no space left for one additional column in the table.
Design your data model for the sake of your domain model, not your domain model for the sake of your data model.
Events are a domain-wide concept, not just a concept in a single Bounded Context.
There are several possible ways for remote Bounded Contexts to become aware of Events that occur in your Bounded Context. The primary idea is that some form of messaging takes place, and an enterprise messaging mechanism is needed.
As [Evans] indicates, the consistency of all Aggregate instances other than the one used in the single transaction must be enforced by asynchronous means.
two mechanisms in a messaging solution must always be consistent with each other: the persistence store used by the domain model, and the persistence store backing the messaging infrastructure used to forward the Events published by the model.
Using Domain Events allows any number of your enterprise systems to be designed as autonomous services and systems.
Almost-infinite scalability is achieved by allowing for continuous repartitioning of Aggregate data storage, as explained by Amazon.com’s Pat Helland in his position paper “Life beyond Distributed Transactions: An Apostate’s Opinion” [Helland]. What we call Aggregate, he calls entity. But what he describes is still an Aggregate by any other name: a unit of composition that has transactional consistency. Some NoSQL persistence mechanisms support the Amazon-inspired distributed storage. These provide much of what [Helland] refers to as the lower, scale-aware layer. When employing a distributed store, or even when using a SQL database with similar motivations, reference by identity plays an important role.
Since the Command objects can be serialized, we can send the textual or binary representations as messages over a message queue. The object that the message is delivered to is a message handler and is to us a Command Handler. The Command Handler effectively replaces the Application Service method, although it is roughly equivalent and may still be referred to as such. Anyway, decoupling the client from the Service can enhance load balancing, enable competing consumers, and support system partitioning