A worked example of using Jargon for Domain Driven Design — Part 1
Domain Driven Design (DDD) is a very powerful technique for breaking down large and complex systems into smaller more manageable chunks.
But, it can be tricky to get started and even harder to manage over time.
That’s what Jargon helps with. It is a platform that helps you and your organisation start down the DDD journey, and makes sure that you get the most out of it.
If you’re completely new to Jargon, take a look at our multi-part series on how it helps you iteratively design APIs and other Data models.
Problem Space:
The problem space for this series will be loosely based on the excellent presentation by Mauro Servienti — All our aggregates are wrong. In it, Mauro breaks down what sounds on the surface to be a simple design exercise: buying a protective cover to keep his lunchtime bananas safe in his backpack. He quickly shows why this isn’t as simple as it initially seems, and presents a pseudo solution for how it can be decomposed into more appropriate Domains.
Really big thing you should note:
This series will not be starting at the absolute beginning, and will make a large number of probably wrong assumptions on how the business of an online retail store works. Any serious DDD initiative should start with a thorough examination of the problem space, ideally using a collaborative process like event storming.
What we will be doing:
We will be using Jargon to design interfaces for a series of DDD based micro services for a retail store that sells, amongst other things, banana protectors. We want to separate the concerns of the problem space into several distinct Domains, each with a single responsibility.
Here are the rough steps this series will take:
- First we will start with a conceptual model that shows what the important resources are, and how they are grouped into Domains. That’s what this post is about.
- Next we will formalise that conceptual model into a Town Plan, with proposed Domains for each one ideated in the conceptual model.
- Then we will create Domain Models and APIs for one, or maybe two, of the interesting Domains to paint a richer picture of what they look like, and how they behave.
Let’s dive in:
If you haven’t watched Mauro’s talk, the high-level set of business problems we want to solve are:
- Show the customer how many of each item in the cart are available for sale. Each time an item is sold, every cart should be updated to reflect the new availability of the items.
- Update the estimated delivery date for the order as each new item is added to the cart. Adding new items to the cart may slow down the estimate, as they may need to be sourced from other warehouses.
- Handling price changes for items that have already been added to a cart. This generally involves removing that item from every cart it was in, placing it in a holding area, and notifying the user about the changes in price.
The specific set of problems isn’t really all that important for this series, but what you should take away from this list is each of the requirements needs knowledge from multiple areas of the business. Naively solving these requirements would tightly couple each of these business areas together and generally lead to a big ball of mud that cannot evolve with the business.
Because we’ve skipped over the business analysis stage (where you really should conduct something like an event storming workshop) Mauro has already identified the main Domains:
Sales
The Sales Domain is helps customers select and purchase items. It sets the prices for items and creates invoices.
Marketing
Handles the store’s catalogue of items with information that helps customers choose what is right for them. It is not concerned with the physical characteristics, only the marketing information.
Warehouse
Inventory management of the company’s items and packing them into orders. It needs to know about the size weight and general availability of the store’s items.
Shipping
The movement of the order package to the customer. Including the ability to track the progress of the package and reporting to the customer when it has been delivered.
Starting to model in Jargon
Now we have a bit of a handle on the problem space and have a bit of an idea of the Domains, we can start modelling this in Jargon.
Let’s start developing a conceptual model of the major resources. This Domain will most certainly be wrong, but it will be useful to help us check our thinking.
Here’s the absolute kernel of the system: a shopping cart with products.
We’ve got three resources at the absolute core of our problem space:
- Product. It’s owned by the Marketing Domain, who add new items to the store, give them catchy names and convincing descriptions. The Marketing Domain are responsible for assigning each Product its unique ID throughout the system, which is used and referenced by other resources (such as CartItem, that has a pointer to Product). This reference is represented by the dotted line between CartItem and Product.
- CartItem. It points to a specific Product by Product.id and stores how many of them are in a ShoppingCart
- ShoppingCart. It’s owned by the Sales Domain, who issue them with unique IDs that will be used throughout the system to correlate business rules and events across different Domains.
Adding another layer
Ok, the next layer out added these resources:
- Pricing. The authoritative source for prices in the store. It has a pointer to the Product, and is identified by that Product’s ID. This is a common theme that is well supported by Jargon.
- Invoice. Has a pointer to the Shopping Cart that the Invoice is for.
- Inventory. Identified by the Product.ID that this Inventory item is for.
- Order. A collection of packed Inventory items, that correlates to a ShoppingCart.
Final touches
The last step is to add the Shipping Domain.
Like the other resources, Shipment takes its unique ID from another resource in the system. In this case it takes its ID from Order, which in turn takes its ID from ShoppingCart. This is important, as any changes to how ShoppingCarts are identified, will flow through to Order and Shipment — helping to keep them cohesive without being coupled.
Wrapping up:
That’s where we’ll end this article, with a conceptual model that breaks down our problem space into a handful of Domains that each have a small number of resources.
The Domain Model for this article is available in the public Jargon instance.
Next time, we will go through creating a Town Plan from this conceptual model. That will give us a roadmap of Domains to create and a place to visualise and mange the work.
If there is anything else you really need to know before the next article comes out, you can:
- check the Getting Started Guide
- leave a comment below
- raise an issue at the jargon issue tracker GitHub repository
- Sign up for a free Jargon account and create your own conceptual model