loading...
Cover image for Domain Driven Design for Everyone Else

Domain Driven Design for Everyone Else

barryosull profile image Barry O Sullivan ・6 min read

I've been talking a lot about Domain Driven Design (DDD) lately, be it at meetups or with clients, so I thought I'd write down my thoughts and see if it helps.

Now, lots of people have written about DDD from a technical perspective (see the end for links), so I'm not going to do that, instead I'm going to discuss DDD from a non-technical perspective.

This is DDD for everyone else.

Solutions Always Overrun

Designing and building a solution is not a trivial problem. It never goes smoothly, and even if it's completed on time (which is never) the solution is usually ineffective and needs to be changed, often drastically. This leads to more delays, bigger budgets and even larger problems down the line.

Why does this keep happening?

Complex vs Complicated

Building a profitable business is a complex problem, and complex is different to complicated.

For example, "taxes" are complicated. There are many, many interweaving rules and processes, but once you know how to apply them (the process), you've solved the problem. It becomes procedural; no thought is required. Just follow the process and you'll be fine.

Building a business is not like that at all, there are just too many unknowns. In other words, it's complex. This is fairly obvious if you think about it. If such processes existed then everyone would just use them. There would be zero risks whatsoever (and this article wouldn't need to exist).

Complex problems cannot be controlled, they can only be managed. Yet we still try to treat business development as a process, because we really want it to be one. Just look at the popularity of "Agile"* and "Lean", especially the heavily marketed, process orientated versions, they re-enforce this illusion (and they also don't work). It's wishful thinking.

Complicated vs Complex

DDD acknowledges this fact, and instead of focussing on rigid processes and hard rules (i.e. one size fits all solutions), it presents techniques to manage and remove ambiguity. The secret isn't following a process, it's about iterating on the problem you're trying to solve.

Focus on the (right) problem

In DDD the domain, i.e. the problem and its resulting knowledge/activities, is the driver of everything else. All solutions flow from problems, so putting the core domain at the centre will naturally lead to better solutions.

For example, say your business is online news. Your "core" domain (the one that drives your business) is content generation, everything else is secondary. By producing better content faster, you'll grow your business. However, if you focus on solving the problem of resizing images (and hire a bunch of developers to write the software) then you're probably not going to grow your business.

DDD brings clarity, and through clarity, we're able to focus.

Talk to the experts

If you want to understand a problem, then you need to talk to the domain experts. A domain expert is someone that understands the problem better than anyone else, and they are able to tell you what's important and what isn't.

In most organisations, the domain experts are not the ones building a solution. DDD helps to bridge the knowledge gap between what the domain experts know and what those building the solution are trying to understand.

This is why a large chunk of DDD techniques have nothing to do with technology, instead they focus on people and ways to unearth complexity and ambiguity. If we're all on the same page, it's easier to move forward.

Building a shared understanding

One key way to gain clarity is to build a shared understanding of the problem, i.e. a domain model. If everyone has the same model in their head, then there's no ambiguity. It helps us avoid overly complicating our solutions, or worse, building the wrong one (e.g. the image resizer above).

Sprechen Sie Talk, huh?

Language is core to DDD. We use language to express our ideas, to explore problems and define solutions. If the domain is complex, then that language will be rich and complex, with its own subtleties and nuance.

The thing is, most people in your business may not share that language. Instead they use their own language to solve problems, which is fine. However, problems arise when two or more people try to communicate using different language without realising it, e.g. the same words but with different meanings. This causes ambiguity and its a leading cause of errors and misunderstandings.

The more people you add to the mix, the worse the problem gets. Take the typical chain of command for example.

The Chain of Mis-communication

That's a lot of room for mis-communication. If you've ever requested a feature and gotten back something that is way off the mark, this is why.

The solution is for everyone to work closely with domain experts to understand the language as the business defines it, and figure out where these language boundaries exist, i.e. when a word is being using in a different context. This enables everyone to communicate (i.e. have shared domain model), leading to less siloing, better collaboration and simpler solutions.

Your solution reflects your understanding of the problem

Any solution you build is a direct reflection of how well you understand the problem. If the solution is good, then you understand your domain, if it's bad, then you don't. This is why quick iteration is so important, it's about tightening feedback loops and iterating on the problem, not building the right solution the first time you try (which never happens).

By using your solution as feedback, you can have further discussions and figure out if you were close or not, which leads to a better domain model, which results in a new solution, which feeds back into your understanding of the problem. It's cyclic and it encourages us to better understand what we're doing, rather than focussing on the solution as the be all and end all.

Faster feedback is better feedback

The faster you can test a solution the better. This doesn't mean you need to build software, that's the most expensive way to test. Instead why not prototype a solution with mockups or even pen and paper? You'll get the same feedback at a fraction of the timescale. DDD encourages upfront discovery and iteration, not writing software for the sake of it.

Feedback loop

That's not to say DDD doesn't talk about software a lot, it definitely does, and it has lots of patterns for writing it, but software isn't the core. A common adage in DDD is that the best software is no software. You see, software adds complexity, so if you can avoid that complexity, you should. A good DDD practitioner will try to find existing solutions to problems, only falling back on custom software if it brings the most value.

Self Improvement

DDD is about the problem of understanding and iterating on problems. This is cyclic, meaning DDD is frequently used to understand itself and improve on itself. You can imagine how fast this feedback loop is, and DDD practitioners are always iterating, discovering and naming patterns and techniques. It only gets better with time.

Conclusion

In short, DDD puts the business and its domain in the driving seat, where it should be. I've been applying DDD for 5 years now and I have to say that my ability to build useful solutions has increased massively. It's helped me hone the techniques and skills I need to understand and iterate on problems. If you want to get better at building solutions, I'd recommend DDD wholeheartedly.

Further reading

Asides:
*This is is a dig at capital A "Agile", the singular methodology that is sold by consultants as a fix all your development woes, as opposed to actual "agile". which is great, as it focuses on iterating on the problem of writing software, adapting to changes.

Posted on by:

barryosull profile

Barry O Sullivan

@barryosull

Lead Developer and Solutions Architect, I specialise in Event Sourcing, DDD and Event Driven systems. PHP and GoLang developer. Enjoys being a smart ass and having a nice whiskey.

Discussion

pic
Editor guide
 

When I started trying to do DDD, I was focused on technical patterns like Repository, Domain Event, etc. Much like "Agile" shops think if they get the processes right, the software will automatically be good; I thought if I used the right patterns, the software would be good. Both of which turn out be patently false.

Your article tells me what I wish I had known about DDD from the start... that it is not about technical patterns (and in fact, I don't believe I use any of them from the book today). It is all about learning the "domain". That's the key to writing good software.

Thank you!

 

Just wanted to chime in on the relationship between agile and DDD, as someone who's more acquainted with the former than the latter. Well, to be more precise, someone with a Scrum background.

I see no reason why these two methodologies need to be at odds with one another, based on this introductory article on DDD. The Scrum that I was taught by the Scrum Alliance has nothing to say about which work items should be prioritised (and so using the domain/core vs non-core dichotomy as a prioritising principle is fine) nor is it particularly interested in how you formulate your requirements (it is certainly opinionated towards user stories, but the common language developed by the DDD method could help you to write clearer user stories in a combined world).

So I think it's unfair to say the goals of the Scrum/Agile processes are an "illusion" and that achieving them is "wishful thinking". I believe they can be used in tandem with DDD and even achieve a level of symbiosis.

 

I'm going respond here with the clarification I put at the bottom of the article.

This is is a dig at capital A "Agile", the singular methodology that is sold by consultants as a fix all your development woes, as opposed to actual "agile", which is great, as it focuses on iterating on the problem of writing software, adapting to changes.

The two are not at odds to each other at all. "DDD" is a way to understand what you're doing from a business perspective, making sure that everything flows from it. "agile" is a way of building software so we always have something useful, adapting to change and new information, rather than following a plan or process rigidly. The two work incredibly well together.

"agile" accepts that software development is complex, in the same way that "DDD" accepts it. The problem is that "Agile", as it has been sold to companies, has been marketed as a process to "solve the problem" of software development. It pretends that software dev can be treated as a predictable process, in other words, as a complicated problem. That's the illusion I'm referring to. "agile" and "Agile" are two different things.

I'm a big fan of agile, I adhere to it's core philosophies. I'm just sad that so many company's have gotten it wrong and think it's just a bunch of processes you follow. It's become waterfall 2.0.

 

I'm a big fan of agile, I adhere to it's core philosophies. I'm just sad that so many company's have gotten it wrong and think it's just a bunch of processes you follow. It's become waterfall 2.0.

In order to prevent confusion for those new, I'd like to point out that there is a myriad of methodologies between waterfall and agile.

Nowadays, it is not a matter of choosing agile or falling into the waterfall.

 

thanks for the post, I can agree.
Most of the time the domain experts are also very motivated in working with you to develop the best possible software in the given time, that makes this job even better!

 

Wonderful thoughts here! I think that I would invert your definitions of complex and complicated however. This makes it easy to think of complex (many-folded) problems being broken down into simple (from simplex; one-fold) problems. The fact that a complex problem sits in a human context takes it to the realm of complicated, which would mean exactly how you've defined "complex."

Love the focus on communication and shared understandings. :)

 

By using your solution as feedback, you can have further discussions and figure out if you were close or not, which leads to a better domain model, which results in a new solution, which feeds back into your understanding of the problem. It's cyclic and it encourages us to better understand what we're doing, rather than focussing on the solution as the be all and end all.

Well said!

 
 

Very well said!