A worked example of using Jargon for Domain Driven Design — Part 3
Welcome to Part 3 of using Jargon for Domain Driven Design.
In this article, we will create two Domains from the Town Plan created in Part 2. This will give you a taste of Town Plan driven development, which involves iteratively creating Domains, and using those to design others.
Which Domain should we start with?
This can often be a tricky question to answer, but equipped with a Town Plan, Jargon makes this quite simple to answer. Our Town Plan shows us the relationships between Domains — specifically which Domains depend on others. Using this, it’s easy to click around the Town Plan and see which Domains don’t depend on any others.
In our case, we’re starting with Marketing.
Modelling our Marketing Domain
After we create a new Domain called Marketing (the process for doing this is covered in our guide to Creating your first Domain), the first step isn’t actually modelling at all. Instead we’re going to start by looking at the behaviour of Products, by creating a state lifecycle diagram.
Jargon’s state lifecycle diagrams are loosely coupled to the Domain — you can name lifecycles after classes, but they’re not actually connected to them — this lets you create lifecycles for abstract items that aren’t being modelled. We’ll see a little layer how to connect the Product lifecycle to the Product resource.
Here’s the lifecycle diagram for Product:
It’s a fairly simple lifecycle, and I need to re-stress that this is a fictional example. Products are created, optionally undergo one or more updates, and are removed.
The key parts from a lifecycle that are used throughout a Jargon Domain are:
- the list of states: Created, Updated & Removed — these become enumeration values for the Product resource’s status property.
- the optional list of event names that trigger transitions: product.new, product.update & product.remove — these will be shown on the Town Plan.
Now, let’s make the Domain Model.
We know from our Town Plan and conceptual model that Marketing is really just a wrapper around the Product resource, so there isn’t really a lot of modelling to do.
The first thing we do is import our conceptual model.
This isn’t a necessary step, but having traceability from your Domains back to your conceptual model makes it easy to identify impacts of changes — after all, that’s the point of having a model in the first place. A consequence of referencing the conceptual model is that it becomes a sort of interface for the system, by defining the identifiers that are used in multiple Domains.
The alternative approach would be to have each Domain that uses the Id from Product, to import the Marketing Domain. That way would work perfectly well, but without the linkage to the common conceptual model. Pick whichever approach suits your needs and works for your project.
Let’s go over what we’re seeing here.
There’s a single class, called Product. We can see that its id property is the imported conceptual model’s Product.id.
The status property is a Code, called Product Status, and on the top right side of the screen, we can see that the ProductStatus code is a lifecycle — this is how we’ve bound the state machine from earlier to the Product class. Jargon Code Tables can be three different types: Manually defined tables, State Lifecycles, or external references. See the Jargon Docs for more info.
We can now Create a Release in preparation for updating the Town Plan.
Adding Marketing to the Town Plan
Now that we’ve created a real Marketing Domain, we can use it to replace the proposed one from the Town Plan.
You can import Domains into a Town Plan the same way you Import a Domain into another. After doing that our Town Plan now looks like this:
Now that Marketing is a real Domain, the Town Plan displays it in green. We’ve also deleted all of our placeholder configuration, such as what classes it will have and what events it will emit.
This is a good demonstration of how Town Plan Driven Development works — you iteratively select a proposed Domain and realise it. It’s also a very clear and visual way to see the progress of the system.
Rinse and Repeat for Sales
Now that we’ve finished Marketing let’s repeat the same process for Sales:
- Create a Domain, and add lifecycles for interesting behaviour
2. Create a Model, import any required reusable types (like Product.id)
3. Release the Domain, and update the Town Plan
Wrapping up:
That’s where we’ll end this entry, with a Town Plan that has two real Domains and the remaining two proposed.
The Town Plan for this article is available in the public Jargon instance.
I hope you’ve learnt a little about Domain Driven Design with Jargon, and now feel equiped to start using it for your own projects.
If you would like some more help:
- 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 DDD project.