About a decade ago, domain-driven design (DDD) was presented by Eric Evans as a new approach to software development in a popular book, Domain-Driven Design: Tackling Complexity in the Heart of Software.
At first, DDD sounded like quite a promising approach, an extremely alluring one for developers working on complex projects. In DDD, once you understand the business domain your software is to address, then all you have to do is build a layered architecture where the business logic is split into two distinct modules core domain logic (which is invariant to use cases) and the application logic (which is the implementation of use cases).
DDD has an analytical portion made of artifacts such as ubiquitous language, bounded contexts, and context mapping; and it has a strategic part made up of aspects strictly related to the supporting software architecture and implementation. The popular rich domain model is just one of many other possible supporting architectures. (A system based on a rich domain model is not inherently better than a plain CRUD system as long as both systems fulfill requirements. The complexity of software stems primarily from the complexity of the underlying business problem.)
The scenario for which DDD provides invaluable help is understanding the intricacies of the business domain. The name of the approach therefore couldn't be more appropriate: domain-driven design. In terms of ROI, the analytical part of DDD is greater than that of the supporting architecture. DDD's ubiquitous language gives a method to learn about key terms nouns, verbs, adverbs used in the business by business experts. By building such a vocabulary, architects and developers can detect when, even within the same company, the language changes and the same term is used to mean different things or to refer to different aggregates of data. Such a case forms a bounded context an area of the final system that exists on its own, much like a black box connected to the rest of the system. Context mapping is the graph that connects contexts together. Each context has its own language, an independent implementation, and an interface to talk to other bounded contexts. The entire system results from the composition of bounded contexts. The ultimate purpose of DDD is having bounded contexts emerge clearly and unequivocally out of gathered requirements.
DDD is not cheating when it comes to tackling the complexity of software design. It puts the focus on the problem domain. However, it turns out to be very easy to do DDD wrong enough that it incurs a noticeable cost.
A common perception is that while there can be clear benefits to using DDD, it is difficult to explain what's required to materialize those benefits. The fact is that over the past decade, many projects succeeded with DDD and many failed. And those that eventually succeeded still went through quite a bit of difficulty. Why?
My belief is that there are a few misperceptions around DDD, the most important of which is that DDD is too often reduced to just building a domain model in the project. But there are some other misperceptions, such as viewing the domain model as needing to encompass every possible action, and viewing domain model artifacts (such as ubiquitous language) as direct implementation details.
I call all of them "misconceptions" literally, a view or opinion that is incorrect based on faulty thinking or understanding. Each perception can be right or wrong depending on the starting point and context. The starting point of DDD is that it serves the purpose of design far before it may serve the purpose of implementation. So, indeed, where are implementation details?
DDD helps discover the top-level architecture and inform about the mechanics and dynamics of the domain that the software needs to replicate. Concretely, it means that a well done DDD analysis minimizes misunderstandings between domain experts and software architects, and it reduces the subsequent number of expensive requests for change. By splitting the domain complexity in smaller contexts, DDD avoids forcing project architects to design a bloated object model, which is where a lot of time is lost in working out implementation details in part because the number of entities to deal with often grows beyond the size of conference-room white boards.
DDD is an effective technique for specific kinds of projects: complex projects with a large problem domain and access to domain experts. From them, a model can be designed from which a programming (generally, OO) implementation can be elaborated. For these projects, it's almost ideal. However, understanding how the domain model is mapped accurately to the programming implementation is critical, and that single step often determines the success or failure of the project. Focus on that, in addition to the core DDD practices, and you're much more likely to achieve a happy result.
Dino Esposito writes frequently on software development topics. His most recent book, the second edition of Microsoft .NET Architecting Applications for the Enterprise was just released by Microsoft Press.