Domain Driven Design
Podcast: Play in new window | Download (51.0MB) | Embed
Subscribe: Apple Podcasts | Spotify | Email | RSS | More
The principles of domain driven design (DDD) make sense, but a lot of the documentation around it is not very helpful for getting your head around the ideas. Domain driven development is primarily about building and designing your applications to be focused on the business needs of your client.
“From the dictionary it’s a sphere of knowledge or activity.”
DDD focuses on the core domain and domain logic or business logic. It bases complex designs on models of the domain. Developers are expected to constantly collaborate with domain experts in order to improve the application model and resolve any emerging domain-related issues.
DDD is a frequently touted development practice, but the literature available on it is sometimes less informative than we’d like. There are some core concepts of DDD that are quite useful even outside of the practice. Once you understand how all the pieces fit together, a lot of the blog posts you’ll see about DDD make a lot more sense.
Episode Breakdown
DDD versus OOP
“To describe this in object oriented terms DDD would be the class and OOP would be the instance.”
15:08 Models
DDD models are designed for large, complex systems (or groups of systems). As such, they are a little more subject to the messy way things are designed in reality than you were probably taught when learning object-oriented programming. Unlike OOP, DDD is an approach to software development, rather than a model for writing computer programs.
17:15 Concepts
Essentially, these are two concepts used at two different levels of software development. OOP is a way of structuring code. DDD is a way of structuring your development practices and terminology to help you make design decisions. In effect, DDD is used when code is being planned, while OOP is used more while it is being written.
18:21 Focus
DDD focuses more on solving problems, than writing code. Just like well-paying software jobs are more about solving problems than they are about writing code. A big part of that is establishing a shared vocabulary between development and the product owners about what is required.
“I’m here to build something to make your job easier but I have to understand what your job is.”
The principles used in DDD will often inform the way you build objects, but you aren’t necessarily restricted to using OOP with DDD. It’s more about managing complexity than anything else.
Domain Driven Concepts
23:08 Bounded Context
This is the context in which a particular domain-driven model applies. Big projects will have multiple contexts. The point is that a database record-centered approach doesn’t capture the way the business handles a particular entity at a particular point.
As an example, consider how a customer might be represented in various bounded contexts of an ecommerce site. A customer for the point of sale is someone with a shopping cart who eventually makes an order and has a method of paying. A customer for fulfillment is someone who has made one or more orders, with varying statuses. For the purpose of customer service, a customer could be either of the above, or a previous customer with no outstanding orders.
27:05 Value Object
A value object is an object that does not have an identity. In other words, it doesn’t stand alone.It must be immutable. Attribute/Property values are injected on the constructor and don’t change after construction.
For instance, an address is useless without the customer that goes with it, but it has its own logic and needs to be passed around as a unit. Typically in languages that allow it (C++, C#, many others), this also means that you’ll override the equality operators so that you can see if two instances of a value object are equivalent.
30:12 Entity
An object that is defined by a thread of continuity and its identity, rather than its attributes is an entity. It contains value objects and other entities and may be mutable. For instance, a customer for the order entry system might have an ID (Identity) and a name and address (two value objects, with the address being a complex value object).
“This means you can change an entity without changing a lot of other things.”
The entity encapsulates domain logic for itself, rather than being changed by something outside. So, instead of another part of the application setting the address, instead it sends a message indicating the address change and the entity handles it internally. This allows validation, among other things. You determine whether two entities are the same thing based on identity. This can make interesting problems if different things are changing the same entities.
35:22 Aggregate
An aggregate is a collection of objects bound together by a root entity, otherwise known as an aggregate root. The aggregate root keeps its internal state consistent by stopping changes to the objects within.
This means that it doesn’t allow references to its internal objects. For instance, a customer entity that contains an subscription entity might process an SubscriptionAddressChanged message, which it would then forward to the Subscription entity, that would then generate a new Address value object.
37:05 Domain Event
This is an object that defines an event that happened in a domain, something the domain experts care about. An event is something that happened in the past, and as such should be described with past tense verbs.
Events are raised in a domain to help make side effects explicit. For instance, if you had a domain event to indicate that a customer’s name was changed, the event might be published as CustomerRelocated and might result in some other part of the application looking at their order history and sending them a housewarming gift if they’ve done enough business with you.
39:03 Service
“This is talking about service classes not API endpoints and Windows Services”
A service is an object that encapsulates operations that don’t belong to a single entity. An example of this might be something like sending an email. Lots of processes might use that functionality, but you would want the logic in a single place.
41:40 Repository
When persisting or retrieving domain objects, it’s common practice to move the persistence logic into a separate repository class, so that you can swap out implementations as needed. Typically, you do not access repositories from entities, but you can retrieve entities from a repository.
Benefits of DDD
45:35 Clean Design
“In other words if I get a junior developer in how long until they are useful.”
Objects have a single responsibility and it is easy to reason about the code without being as concerned about side effects. This lowers the total cost of ownership of the application over time. This makes it easier for the code structure to reflect the priorities of the business. You can more easily focus on items that provide a business value if your code is structured according to the business domain instead of based around however the developer approached the work.
49:45 Common Vocabulary
It also helps the organization to build a useful model of its domain(s). This creates a common vocabulary for things, rather than confusion. This makes collaboration between teams much easier. In my experience it also shortens meetings because of improved understanding.
51:00 Domain Expert Involvement
It allows the domain experts to get involved in software design in a useful way. This also helps the domain experts get their own understanding lined up, since they may well have gotten into the organization with widely different experiences. This is also a good way of preventing knowledge silos in different parts of your app, which reduces the risk that the company faces if key personnel leave.
52:20 Continuous Adjustment
“If you write a column in a CRUD system you have to account for that column throughout the system.”
It allows for continuous adjustment of the model without as much pain as doing things using CRUD. One of the big problems with CRUD is the amount of effort required to change the data model to accommodate changes. Because the DDD model is separate from the database storage model, it often makes changing the code easier or at least reduces the size of changes.
IoTease: Tutorial
Build Alexa Skills
Build your own Alexa skills using AWS Lambda functions. You can use just about any modern language to build a Lambda function but the most popular is Node.js. You’ll have to register with Amazon as a developer to even get to their tutorials. However, Pluralsight has a tutorial for setting up a basic skill.
Tricks of the Trade
Make a data dictionary as early as possible when working on a project. Make sure you know what words mean before you start talking too much or acting upon them. It save a lot of pain.