How complex can software become before it is impenetrable to its
developers? That's the issue Domain-Driven Design seeks to address.
When complexity gets out of hand, the software can no longer be
understood well enough to be easily changed or extended. By
contrast, a good design can make opportunities out of those complex
features.
DDD is a philosophy that grew out of a book, Domain-Driven
Design, by Eric
Evans, that discusses the language of patterns. The premise of
domain-driven design is two-fold:
- For most software, the primary focus should be on the domain;
and
- Complex domain designs should be based on a model.
Domain-driven design is not a technology or a methodology. It is
a way of thinking and a set of priorities, aimed at accelerating
software projects that have to deal with complicated domains. In
DDD, you start your application architecture by defining the
ubiquitous domain language. You map out the domain objects as the
user would see them.
A real-world example
Take, for example, the car rental industry. Car rental
companies rent their cars by rate -- a daily rate, a
weekly rate, etc. Each rate has a car,
location, pickup date, and return date.
So, in our domain language we would map out what a Rate
is. We'd follow this up by defining a Car and a
Location. These are three Entities.
What attributes come to a user's mind when they think of these
entities? What operations can the user perform on them? Well, When
a user has chosen a Rate, they will book it. So,
an operation on the Rate entity may be Book. The
result of a user booking a Rate would be a
Reservation. So, Reservation becomes another
entity for our model. What attributes are associated with a
Reservation? What operations?
Once the architect has walked completely through this process,
we end up with our Domain (in this case, Car Rental) completely
mapped out. This is the ubiquitous language that will be used to
describe everything that happens in the application.
The difference with Domain Driven Design is that these domain
terms, like rate, car and reservation,
feed directly into the code that is written. To continue the
example, having defined an entity called a Rate, we
therefore have a class called a Rate. This has the
properties of Car, Location, pickup
date, and return date. This also has a method called
Book that returns a Reservation. At this level of
the application code we are not thinking at all about how the data
is going to be stored or communicated to the back end applications.
We are thinking completely about the domain objects that the user
would identify and understand.
Entities are one of five main patterns used in Domain Driven
Design. The others are Value Objects, Repositories, Services, and
Factories.
The significance
Why is this important? Because the most significant complexity
of many applications is not technical. It is in the domain itself
-- the activity or business of the user. Car rental, the example
cited here, is simple compared to domains like income tax returns
(TurboTax) or business intelligence (SAP). When this domain
complexity is not dealt with in the design, it won't matter that
the infrastructural technology is well-conceived. A successful
design must systematically deal with this central aspect of the
software.