… something on Domain Driven Development
I’ve just completed all three days of Vaughn Vernon’s IDDD (Implementing Domain Driven Development) Training Course. I’m now sat in my garden with a much needed cup of tea, brain not quite dribbling out of my ear, but not far off. It was an intensive three days. Thankfully it’s now a warm and sunny Friday evening of a Bank Holiday weekend.
Redgate got Vaughn, a leading DDD figure, over for some on-site training as part of an effort to up our game both on software design for some upcoming initiatives but also our broader technical training given to our Engineers.
Before we got started we were asked to read Vaughn’s IDDD book, and also access the equivalent videos, DDD Live Lessons, which you can do so on SafariOnline, and for free with a 10 day trial. Personal hint, you can speed the videos up too until you find a topic you need more time to absorb.
The course covers a lot. Obviously this includes what is DDD (Domain Driven Development if it wasn’t clear), but then many supporting tools, both Technical, exploratory and communication, and heavily emphasises talking to your users.
Strong Opinions, Weakly Held
When the course was announced I was really keen to attend as DDD was something I’d discussed and heard much about, without ever having fully read up on the subject.
Whilst I found much of it eminently sensible (indeed I mostly consider myself to follow it already), I wanted to know and understand more about the techniques to challenge my own thoughts and ideas that I’ve gained from experience. Partly to validate some of my thinking, but also to learn.
However I was also conscious that there was limited space and maybe better justified people to attend (we wouldn’t have wanted to fill it with just Tech Leads for example). In the end I only attended as someone couldn’t make it.
At Redgate we have a maxim, for anyone wanting to progress as a Software Engineer (or indeed as anything), of Strong Opinions, Weakly Held. I went along with an open mind realising I may hear a contrary view.
Domain Driven Design
Firstly, what is Domain Driven Design? Well, at one level it’s merely having small, discrete, decoupled models, isolated within their own Bounded Context, within which you use a consistent Ubiquitous Language (speaking the ‘language that your users use’ as someone once said). Where there is a related but separate ‘domain’ then that is a separate Bounded Context.
As an example you might have one Bounded Context for cutlery (knives, forks, spoons, etc) and crockery (bowl, plate, etc), they are related, but separate.
Another, more illustrative example perhaps, would be one Bounded Context for vegetables, and one for herbs and spices. Notice here, the term “Pepper” can appear in both Ubiquitous Languages but with two different meanings — black pepper, and capsicums. Vaughn uses the example of the word Policy which can have many different meanings across an Insurance business.
Back to Object Oriented Basics
The third essential aspect of DDD is that domain objects remain true to traditional Object-Oriented principles, so their internal logic and their data sit together, inside the Object. The object does and is not done-to as in much of modern programming.
This is the part of DDD that I struggle with. I find it easier to reason about software I’m writing when the state and logic is separated. In a project I was working on two or three years ago, doing this separation was essential to understanding the complex mathematical algorithm we were working on.
But I think this is also an area DDD and I mostly agree on, the problem is objects that are open access on the data they are supposed to be encapsulating — every field has a setter and can be modified by anything else. This is the real danger, and on the project I just mentioned there was no constraint; and this gives you spaghetti code; or the Big Ball of Mud (BBoM) Vaughn talks about.
Throughout my career I have worked to truly encapsulate internal data and where at all possible make it immutable. Interestingly Vaughn regarded use of getters (getName()) as a code smell; remember C#-ers this is implicit for you, just because you don’t have the get-and-() bit doesn’t mean you’re not using them!
A related point Vaughn thought poor programming was non-properly constructed objects, ie you ‘new up’ an object by calling a default constructor and then run through multiple setters. I *always* ensure objects are properly constructed and intensely dislike temporal dependencies of any type (call this, then that on the same object).
Design by Entropy
Vaughn also makes the point that a tendency in many companies where the required strong Technical Practices required for Agile are neglected, that developers just start coding; if no design is applied and if not refactored into a design then you end up with Bad Design by default.
Good Design takes effort. The absence of a design is not No Design but whatever turns up which is likely to be poor.
Or as I put it “Not designing is Design by Entropy”.
Anemic Domain Model
A number of years ago I was working with a team on a card payment processing application. Over some months I had slowly introduced some structure to what was becoming a BBoM.
This put the software on a far firmer footing, but then one of the team read a DDD book, and started complaining that we had an “Anemic Domain Model”. Which left me a little exasperated; especially given where we’d come from.
I’ve always found the term Anemic Domain Model to be fairly perjorative, whilst I fully buy into strong encapsulation, the blending of logic and data (as I’ve already described) is more debatable. I’ve also used logic in the object to ensure internal consistency. But if that is what is meant then I have to admit my software might well be Semi-Skimmed. Healthier for it though I believe.
I also call to mind, a developer I had the utmost respect for, a Spring project committer, and usually quietly understated, describe that some of the worst designs he’d come across were done in the name of DDD. But I came to the course open-minded, keen to learn and to understand what I’d been missing.
This to me was the contentious part of the course, and I’m still mulling it over. Can you be doing DDD without this?
Other (Supporting) Techniques
The course also covered Event Sourcing, and much of the coding exercises focused on software of this design. This is where the software communicates by a message bus rather than direct method invocation. I recognised this programming style from a project I worked on almost a decade ago, though this was never explained to me; so some of that started to make sense…
Related to this, but a step further was CQRS — Command Query Responsibility Separation since you ask. Effectively this is having a clear distinction between pure queries with no side effects (I’ll return to that in a moment) which are therefore read-only, and Commands which change the state of the system in some way (of course an audit function will muddy the water). I remember discussing this and regarding it as reasonably good practice, doing it when I could. It also reminded me of using a PUT in http (a command), getting nothing but a 202 status back, and then confirming it had worked with a GET (a query).
The no-side effect mantra is a good rule, and I have long adhered to this, remembering when I worked with my now-colleague Jeff Foster before, and you often hear developers saying to each other “Don’t do that — Jeff doesn’t like side-effects”.
On top of which I’ve always tried to return something from a method so that you are able to detect that something happened — otherwise it’s just blind faith. This is what I really struggled with at a startup last year; everything was a void and there was no way to test or assert on it; therefore it wasn’t really tested. We were building Castles on Clouds.
Other Collaboration and (Collaborative) Design Techniques
Another area Vaughn covered included Event Storming (as opposed to Sourcing). This is a technique for collaboration with your Domain Experts, and involves examining the timeline of events through your system, both happy and unhappy path, and thus covering a wall with post-it notes Bayeaux Tapestry style.
We also considered the relationship between teams and therefore their software systems (sound the Conway’s Law Klaxon), be that Partnership, Conformist, RPC, REST and/or using a Anti-Corruption Layer or Published Language.
It’s been a really intense three days, but well worth it. The exercises on the first day were a little vague so it wasn’t quite clear what problem we were trying to solve, but Vaughn had only just made it in time from the States due to snow storms and did admirably well on the first day given his jetlag; his suitcase only turned up at the end of day two with the workbooks (which would have helped the exercises).
The Event Storming exercise however was well worth it and a great way to explore the Problem and Solution domain.
The exercises were non-trivial and require serious thought, but leave good room for discussion and exploration; they were available in both Java and C# (and PHP for the record) and it was easy to switch between the two.
Many of the concepts required a clear head (one of the pre-course actions was to get a good night’s sleep!). Vaughn has clearly lived and breathed all of this for many years, written books on the subject, was very personable, and a pleasure to work with over the course.
I’m going to be encouraging my team to read his intro book, and watch the videos so we’re all on the same page, or at least using the same lingo.
Thanks Vaughn and Redgate!