Book Review: Domain-Driven Design
I just finished Domain-Driven Design by Eric Evans. This is a review. A partial summary from the back of the book reads:
…This is not a book about specific technologies. If offers readers a systematic approach to domain-driven design, presenting an extensive set of design best practices, experience-based techniques, and fundamental principles that facilitate the development of software projects facing complex domains. Intertwining design and development practice, this book incorporates numerous examples based on actual projects to illustrate the application of domain-drive design to real-world software development.
Right off the bat, let me address the key question: Should you read this book?
If you’re a software developer that works with at least 2 other software developers on code that you don’t throw away (IE prototypes), then yes, you should read this book.
In my personal experience, both architecture and business domain constructs are almost entirely ignored in the mobile development industry. I can’t say whether this is also true for web services, desktop applications, etc. — but it sure seems to hold for Android, iOS, and client-side web development.
This avoidance of architecture and business domain might be acceptable if strong solutions could exist without them. However, speaking again from only my personal experiences, even medium scale mobile apps benefit immensely from thinking about the application’s structure. Far too often we simply throw lines of code at problems that could be solved with simple structural changes.
I read Domain-Driven Design because I’m always looking for new insights about how to bring structural benefits to messes of code. For example, I’ve written about the need to Package Wisely, I’ve pointed out the differences between Objects and Data Structures, and I’ve recommended that we always code for the next developer. With that perspective in mind, I’ll tell you my thoughts on the book.
Domain-Driven Design does an excellent job of weaving business realities into software development considerations. For example, Evans remarks, on multiple occasions, about how model consistency requires constant communication and developers that are divided by team/location do not engage in constant communication. As a result of this business reality, recommendations are made about segmenting the code to allow for effective modeling within independent teams. These strategies even take into account political problems between teams, as well as integrating with overburdened teams and legacy systems.
Moreover, Evans establishes a claim that many developers rail against, but which rings especially true to me: All developers on a team do not need to share the same solution.
The claim doesn’t mean developers should use arbitrary solutions. It means developers shouldn’t bind each other to a singular solution when they might be solving fundamentally different problems. Two teams working on your app might have a concept of a “Customer”, and they might have a Class called Customer. But maybe Team A needs a customer within the context of billing, and Team B needs a customer within the context of a support system. Should we use the same Customer Class for both teams? Probably not. We should probably have a billing.Customer Class and a support.Customer class. Each Customer then contains only the behavior it needs for the job it exists to do. Nonetheless, I have seen great opposition to approaches like this — detractors speak of the “unnecessary duplication” but in reality its not duplication, and its very necessary. Evans seems to promote the perspective of locking down “Bounded Context”s for similar reasons.
Thus, when it comes to structuring software in a way that accounts for business structure, I think Evans is right on the money. Evans promotes modeling focus and practices in a paradigm that also allows teams to operate independently. Its architecture without the dictator.
And if you’re wondering why you should read the book after my eloquent description of the problem and solution, its because Evans provides numerous terms to help describe and communicate these business-integration situations. If you can’t discuss these issues with your coworkers then you probably can’t solve large scale structural issues.
Domain-Driven Design is not without its drawbacks.
The book is written in a dialect approaching that of academia. Big words, long sentences, and introduction to concepts that are so abstract that they would be unintelligible without the accompanying examples. In fact, some parts continue to be unintelligible even with the examples.
Its not that Evans doesn’t know what he’s talking about. I’m sure he does. And I’m sure what he’s saying is very important. But a lot of the book reads as though Evans were reliving real situations in his head while writing about them in a completely generalized, nondescript fashion. Its almost as if he was trying too hard to speak in generalities instead of simply saying “Hey we messed this thing up. We should have done it this way.” or “Hey we had this hypothesis, we followed through with it like this, and everything worked out.”
Evans tends to present arguments in the opposite order of how I think he should. Rather than begin with the inconceivably abstract and then proceed to the specifics, I think his arguments would have been far stronger by starting with specific problems and then generalizing to the abstract problem/solution pairs.
In addition to the book reading like a research paper, the first few chapters were very difficult to sit through. I was pretty worried early on that this book was going to be a dud. Luckily, the utility of the writing steadily increased as the chapters moved along. By the end of the book I was glad I read it.
Lastly, I take some issue with a couple of design concepts that Evans treats as axiomatic. Namely, not differentiating between data structures and objects, and promoting the notion of a “layered architecture.”
First, the difference between objects and data structures. This is a topic I covered in Objects vs. Data Structures. Our community is awash in developers that seem to believe that objects exist to hold data. But this is obviously false. If objects existed to hold data then a C struct and a Pascal record would both be objects, and those languages would be “object oriented.” But they’re not.
Objects exist to model behavior. Evans seems to miss this point throughout Domain-Driven Design. Most of the book feels more like a discussion of Entity-Relationship Modeling for relational databases than it does a discussion of Object-Oriented Design.
But perhaps I’m missing something. Maybe Evans’s use of objects to hold attributes and point to other objects is legitimate. I’m not sure. But if Evans is correct in his use of objects then I do know that there is a fine line between Evans’s use and the absolutely incorrect use of objects that proliferates our industry. So developers should take care to avoid the pitfalls of “Struct-Oriented Design.”
Now on to the notion of “layered architectures.” Much like the object modeling issue, I don’t know if layered architectures are a legitimate approach or not. But what I do know is that I’ve never seen it done effectively. I mean sure, layers are how networking protocols are established, but I‘ve never seen layers work out in object-oriented systems. Layers seem to promote the idea of having abstractions pointing to concretions which completely destroys the notion of abstraction in the first place.
So I take Evans with a grain of salt when it comes to his use of objects and his promotion of layers, but overall I still recommend the book and there should still be plenty of useful ideas that are definitely correct.