I was talking to a colleague & fellow Domain-Driven Design obsessive @thoughtworks the day before yesterday.
Their gig wasn't using #DDD, and while they knew it would bring benefits, they had no remit to start a full-on adoption effort.
And so the conversation turned instead to how they can make their little part of the codebase a #DDD haven, and keep themselves sane in the process.
Now, the typical mindset of a grafting Dev shipping quality code these days is SOLIDSOLIDSOLID, and while that's generally no bad thing, is there a similar place for #DDD in that scene?
Can you get value from #DDD even when there’s not a hands-on modeller giving you permission to do it? Or a team lead trying to keep your team’s models and services clean despite the chaos that surrounds them?
Yes; yes you can.
The key patterns (and discussions) are in the “SUPPLE DESIGN” chapter of the Blue Book, hiding out before the more famous but far larger-scale BOUNDED CONTEXT-based patterns and after the more fundamental structural patterns and concepts.
What we’re going to talk about will obvs build 100% on top of UBIQUITOUS LANGUAGE but won't include many of the other rightly-famous #DDD biggies.
What!?! That means no ENTITIES, AGGREGATES, REPOSITORIES, ANTI-CORRUPTION LAYERS etc? Are they all out of the question?
Yup. Remember the mission. The impact of all of these - without wider buy-in - would be too great. We’re improving, not causing chaos. So what else is there?
There’s loads. Sadly, far too many of us perceive #DDD as an all-or-nothing thing.
The Blue Book alone contains tons of awesome and more importantly standalone nuggets that you can employ to make your life as an individual dev just that little bit better.
Before we dive in I want to highlight one last thing. Key to all that follows is the awesome support we now have for renaming things.
I’m old enough to remember the days before right-click-refactoring. I also vividly recall the pain with renaming-tree conflicts.
That used to be a good argument from leads and architects against self-driven renaming (or heaven forbid, package-tidying). Now however, if a name is bad, you can change it preposterously easily, and without causing your co-workers a world of pain.
So with this reassurance, and because we’re doing #DDD, renaming is the place to start. Begin looking at names of everything; packages/namespaces, classes, attributes, and operations.
Make them explicit. Make them temporarily long and ugly if needs be, but _please_ make them descriptive, and make them domain-focused. If you can’t, that’s an excuse to have a little #DDD chat with your BA or other domain-language talker.
Our goal? We can have a quote from the Blue Book here: “name classes and operations to describe their effect and purpose, without reference to the means by which they do what they promise.” (p247)
But wait: “this relieves the client developer of the need to understand the internals these names should conform to the UBIQUITOUS LANGUAGE so that team members can quickly infer their meaning.” (p247)
We could stop here. We’ve added some value: we have some nice new names for our classes/methods. But perhaps we’d like to go further.
Enter Guerrilla #DDD move 2: SIDE-EFFECT-FREE FUNCTIONS.
Again the initial elements of this second Guerrilla #DDD move aren’t surprising: “place as much of the logic of the program as possible into *functions*, operations that return results with no observable side effects.” (p251)
Nothing too earth-shattering here, but there are subtleties: “after completing the refactoring to separate modification from querying, consider a second redacting to move the responsibilities for the complex calculation into a VALUE OBJECT.” (p251)
“The side effect often can be completely eliminated by deriving a VALUE OBJECT instead of changing existing object state, or by moving the existing responsibility into a VALUE OBJECT.” (p251)
You can use them (ASSERTIONS) in many places, but as you refactor your part of the codebase into clean, domain-aligned modules, producing a design where larger parts are now built of smaller ones, one command many invoke many others.
Eric Evans defines this problem crisply: “when side effects of operations are only defined implicitly by their implementation, designs with a lot of delegation become a tangle of cause and effect. [...] The value of encapsulation is lost.” (p255)
Combined with our INTENTION-REVEALING INTERFACES, ASSERTIONS allow you to explicitly think in design-by-contract terms, and deliver easier-to-reason-about code.
If INTENTION-REVEALING INTERFACES are like our preconditions. ASSERTIONS are their post- counterparts.
State these post conditions of operations and invariants of classes clearly in your code. Ideally your programming language of choice will allow this (e.g. Java does).
Write unit tests for them.
And the benefit? Eric again: “humans don’t just compile predicates in their heads. They will be extrapolating and interpolating the concepts of the model, so it is important to find models that make sense to people as well as satisfying the needs of the application.” (p256)
So far all of these interventions could (should) be very small. But the real joy of #DDD is when we follow the domain towards a *significantly* effective refactoring. It’s what hooks me anyway. Can we get to one of these without "doing #DDD?"
Yes, even within our limited permission-scope, these interventions can lead to one. How? Because by doing all this we ought to be moving towards clean, consistent CONCEPTUAL CONTOURS.
Evans again. As you refactor “observe the axes of change and stability [...] and look for the underlying CONCEPTUAL CONTOURS that explain these shearing patterns. Align the model with the consistent aspects of the domain that make it a viable area of knowledge.” (p261)
"The goal is a simple set of interfaces that combine logically to make sensible statements in the ubiquitous language. And without the distraction and maintenance burden of irrelevant options.” (p261)
And the best bit? “This is typically the outcome of refactoring: it’s hard to produce up front. But it may never emerge from technically oriented refactoring; it emerges from refactoring towards deeper insight.” (p262)
That’s it. What have we ended up with? A supple design, even if it’s only in a limited part of your codebase. It’s code that’s got a far lower cognitive load, one which can be functionally composed, has loads of useful automated tests on it, but most importantly ...
... it's solving problems for the users in your domain.
• • •
Missing some Tweet in this thread? You can try to
force a refresh
In my life as a consultant I've seen many peeps adopting Domain Driven Design.
Things go wrong a lot; and frequently the problems start in the initial stages.
So I made a thread to share my thoughts and tips on the subject of starting out.
(Please comment. I love feedback.)
When I say "Domain Driven Design" I'm talking about the design process introduced by Eric Evans (@ericevans0) in his 2003 book "Domain-Driven Design: Tackling Complexity in the Heart of Software". amazon.com/Domain-Driven-…
This book, while incredibly readable (one of my top three books for devs) also puts people off with its heft. (Understandable.) There are related works too (Implementing Domain Driven Design by Vaughn Vernon (@VaughnVernon) being the most well known.) amazon.com/Implementing-D…
Arrived for the @sainsburys Agile Community Autism Awareness Workshop at @MSFTReactor. I'm excited to see what they have in store for us...
Catherine Leggett from the @nationalautisticsoc kicks us off. Focusing first on workplace adjustments.
Catherine Leggett: "We're not diagnosed on our strengths, these (from the diagnostic criteria) are "difficulties". But these are strengths in different circumstances.