top | item 28667359

Domain-Driven Design

247 points| ingve | 4 years ago |verraes.net

191 comments

order
[+] LennyWhiteJr|4 years ago|reply
Seeing a lot of hate for DDD here so let me offer an alternative point of view from someone who advocated for DDD on my team.

When I joined, my team had been building the backend for the first version of our app for about 4 months. I would describe the state of the code base when I joined as an 'Anemic Domain Model' as defined by Martin Fowler

- There was a 'domain model' in the loosest possible sense - Each model type was just a POJO with raw getters/setters for each field - Almost all fields were primitives (mostly strings with a few int/doubles/dates) - All validation code for these types was done in application code and was fragmented throughout the code base - Internal DB identifiers were fully exposed into the code model - Internal service types were liberally mixed with external service types - No notion of aggregate roots - every entity was just accessed ad-hoc

It was a highly unsustainable approach, and one of the first thing I did was attempt to implement strategic DDD in the areas that were the most painful. This included

- Adopting rich value objects to represent domain concepts instead of raw strings - Enforcing business invariants inside the model classes - Enriching the domain entities with methods that matched business behavior and performed validation - Creation of repositories that shifted much of the persistence details out of the application code - Defining aggregates based on our required access patterns which simplified our data access - Bounded contexts for our internal domain - mapping external service types to our own internal representation

The result of all this was the creation of a core 'domain model' that captured business behavior expected of our service and most importantly, ended up significantly simplifying the rest of the application code. If DDD makes your app code more complex, you're doing something wrong.

[+] mixmastamyk|4 years ago|reply
Perhaps the problem is inventing a new language for good application design. Uncharitably, this explanation sounds as if you've taken a description of modularity, type-safety, and maintainability and run it through a randomizing jargon thesaurus.

If an experienced developer can barely understand you, there's a communication problem.

[+] stepbeek|4 years ago|reply
This sounds like another data point of many in this thread that point towards DDD as a philosophy working very well, while enforcing technical techniques advocated for in the book being hit-or-miss.

This makes intuitive sense to me: it’s much easier to define a principle that applies in many situations but much harder to define concrete technical implementations that do.

In your situation it sounds like the multiplier you applied was in pushing your team towards a rich domain. That’s a much more sensible approach than, say, using CQRS everywhere.

[+] Fiahil|4 years ago|reply
I attended a few DDD meetup a few years ago, and it never quite made sense why would you engage in this kind of architecture nowadays. The room was filled with experienced Java developers with deep Enterprise Software(tm) knowledge.

Then, I started working as an AI Software Engineer (mix of a software engineer + devops + data scientist), and it all clicked. DDD is a wonderful design pattern for anything related to Data Science, AI, ML. Why ? because 90% of your problems is retroactively making sense, organizing, sorting, filtering, aggregating all the data you got from your favorite Data Base/Lake/Wharehouse. DDD let you have a unified language, invariant definition and expectations between your existing business challenges and the analytics your are running on it. It's very good for validating assumptions accross a dataset, for example: Sales amount can never been < 0 ? Let's check that... Oh well, you forgot about returns, so now you can define them and be explicit when to include or exclude them.

[+] MihaiSandor|4 years ago|reply
And the most important thing is that you have clear benefits in communication using a common domain language.
[+] adam_ellsworth|4 years ago|reply
> invariant definition

What's that? I haven't encountered that terminology before.

[+] seanwilson|4 years ago|reply
> Software for a complex domain requires all designers (engineers, testers, analysts, …) to have a deep, shared understanding of the domain, guided by domain experts ... That understanding is rooted in language: the domain language should be formalised into a Ubiquitous Language (shared, agreed upon, unambiguous) ...

> DDD is not prescriptive. It doesn’t have rules of how to do it, and is open to new interpretation. It doesn’t prescribe methods, or practices, and even the patterns in the book1 are meant to be illustrative rather than a final set. ...

> That makes DDD notoriously hard to define.

I don't know anything about DDD, but if you can't concretely describe it and how it's different to how teams naturally work together, how can it be actionable and what stops it becoming another cargo cult when nobody can agree on what it is?

[+] jdlshore|4 years ago|reply
The book that introduced the term, “Domain-Driven Design” by Eric Evans, is thick but excellent.
[+] keithnz|4 years ago|reply
I find it hard to understand how you'd get the essence of the idea from some of these descriptions, I was lucky enough to be at OOPSLA when Erics book came out and he had a session on it, I think he explained it pretty well, not sure if there are online presentations of his that are good, his book is good, but has a lot of extra more "technical" stuff to deal with how to implement it.
[+] jeltz|4 years ago|reply
Agreed, my issue wity DDD is that it is based on a bunch of good ideas but very little of it is actually actionable.
[+] superzamp|4 years ago|reply
DDD always felt like a bad adaptation of the emperor's clothes for programmers to me.
[+] softveda|4 years ago|reply
In my 22 years of career in Software starting as a developer I have seen DDD used only one time successfully and appropriately. All other attempts were half baked and over engineered mess.

The one time it worked is a very complex domain of insurance policy administration. It had highly complex business rules and had to maintain invariants. The original developers were all experienced and senior from a consulting company. I joined as a permanent member of the team before handover.

The problem was that over several years it was a hard time to get new hires up to speed to maintain the complex code and test it. Moreover even the ubiquitous language starts to change with new CEO, SMEs retiring, change in market etc. E.g. Member became Customer. Now you either refactor the entire codebase or have the code different to the new business jargon. Guess which one was chosen? Over time it became hard to refactor. I have now left the company many years back, but I am assuming this code still lives.

Then I worked in enterprises where this kind of core systems were built in some humongous monolith like SAP, maintained my an army of people from WITCH companies. All the digital apps, web portal etc. was a frontend, API and caching layer. The DDD complexity was in the bowels of SAP or PEGA or Dynamics etc.

[+] tinco|4 years ago|reply
So this is a very fundamental explanation of DDD, the kind you might learn at university. But the last time I researched DDD there was a very concrete architecture associated with it, and I didn't really understand why. Every DDD article would also introduce CQRS for some reason, it seems they are inextricably connected, at least for web application development. Anyone got a good story on that?
[+] ToJans|4 years ago|reply
I think the definition of DDD is abstract on purpose. I proposed a one-liner a couple of years ago [0]:

* The essence of DDD: make the implicit explicit (language, boundaries, code) and evolve your model so it matches the domain *

But to be honest, in hindsight I think it was nothing more than a drip in the ocean, and does not clarify a lot, unless you are already well versed in DDD; it's like those explanations about monads...

As for the CQRS-as-a-top-level architecture:

There are a lot of "beginner experts" and self-proclaimed thought leaders emerging, as DDD is getting more popular... (~= Agile movement)

CQRS-all-the-things is typically a phase that you go through if you are studying DDD. (I've been there, done that, got the T-shirt.)

In my personal opinion a good heuristic to detect "beginner experts" is that they prefer to use a lot of DDD lingo, and focus on the more technical aspects instead of truly trying to understand the business domain first.

Update:

Added the first paragraph with an attempt for a DDD definition.

[0] https://tojans.me/posts/ddd-in-a-tweet/

[+] dm3|4 years ago|reply
Unfortunately there isn't a single definition of DDD accepted by everyone. At its core DDD is about the practice of software design which puts Domain - user language and problems - first. There are no technical considerations.

ES (Event Sourcing) and CQRS are technical patterns people like to use while doing DDD because of various reasons, but they're in no way required to practice DDD.

[+] macando|4 years ago|reply
It's because a popular book on DDD "Implementing Domain-driven Design" uses CQRS in its examples. If the book was written today CQRS would probably be replaced with Serverless computing or something even more trendy.
[+] amw-zero|4 years ago|reply
I'm not advocating for CQRS or any of that, I've personally never used it on a project. But, the reason that architectures are associated with DDD is that DDD is fundamentally a philosophy or an idea. Certain software designs achieve that philosophical ideal better than others.

For example, DDD stresses the idea of an "isolated domain model" - and that has a very practical reason, being that your business rules are already complicated enough so mixing in database transactions, HTTP caching, response serialization, authorization, etc. etc., into your domain logic makes it harder to understand. You want to be able to have a conversation with a customer / domain expert where they explain something and you can adjust the code quickly to meet their needs. That's the ideal goal at least.

So some patterns enable that goal better. For example, this implies that you need some kind of data access layer pattern so that code that cares about the database is separate from code that cares about domain logic. Well, there's a million different ways to get that separation, and they have different tradeoffs, and like everything else, certain patterns become trendy. That's what's going on with CQRS. People feel that it leads to a better expression of the domain model, because creating data and querying it are often radically different from the customer's perspective.

Whether or not that goal is achieved, I'm not sure. But that's the reason people are experimenting with patterns like that, as I see it.

[+] raducu|4 years ago|reply
DDD is sort of the OOP of OOP, without the clever Design Patterns. -- DDD is the kind of principles most OOP people can learn and apply in the same mechanistic way the apply OOP principles and that actually do pay off (unlike design patterns which are really clever but have very little impact in real world).

CQRS is associated with DDD because it is the kind of smart pattern made out of bits that the other smart patterns frown against -- like data duplication/denormalization.

[+] torginus|4 years ago|reply
I clicked this article to find out what DDD is as I've heard the term and was curious to learn more about it. Unfortunately, this article does very little to enlighten me besides the very basic common sense stuff, like understanding the business domain/keeping in close contact with the people who do.

The above idea is hardly revolutionary anyway, I'm sure many people operated this way DDD or not.

This seems like another one in the endless stream of innovative project management methodologies that promise to make everything better, but whose main purpose is creating lucrative make-work opportunities to the next batch of consultants and evangelists.

[+] pmontra|4 years ago|reply
I didn't read the PDF but it seems a way to formalize the usual analysis of customer requirements. It goes like this:

1. Understand the business of the customer, or any requirement won't make sense.

2. Learn the jargon of the business, or you won't be able to communicate.

3. Use that jargon when naming database tables, software modules, variables, everything, or you'll have to translate between your possibly abstract names and the jargon of the business.

So, apparently nothing new but I should read the PDF (too bad it's not HTML) because there could be new useful ideas about the process.

Edit: oops, the PDF is only that page as PDF. I'll google for it but does anybody have a good link to a detailed explanation of the method?

[+] nocture|4 years ago|reply
DDD strikes me the software version of Agile sometimes. The ideas and philosophy behind are good, but ends up being taken as a silver bullet. If you do this you will have a good architecture and your software will be well architected. Especially in the .NET world i've seen DDD being branded together with CQRS as "Clean Architecture" which in reality turns out to be a mess of layers and separations.
[+] arkh|4 years ago|reply
> DDD strikes me the software version of Agile sometimes.

DDD is more about managing your business software needs than making software. If you read "Implementing DDD" a good thing to take from it the fact you should focus your efforts on your business core value add. It's where you put your best developers, architects and money. Anything outside this core will get less resources and can often be outsourced.

And to evaluate what is this core and what is needed, you need your technical team to speak often with the domain experts. Using some common language.

The coding aspect is itself agile as usually there will be miscommunication at first between your tech team and your expert giving you a less than good result. More communication, more knowledge shared and understood will make you think differently about your product and its architecture: that's when you refactor.

[+] necovek|4 years ago|reply
Like the original post fails to mention any stakeholders when it comes to developing "Ubiquitous Language" (it enumerates "engineers, testers, analysts, …", and I don't think ellipses does any justice to them), most people forget that DDD is about modelling the real world before you start coding.

My experience is that, unfortunately, majority of developers are either not experienced enough, or smart enough (these are closely related), to keep the abstraction creep at bay and apply only meaningful abstractions. And others are simply not interested enough, and they know they can get a LGTM with following misjudged patterns.

They also jump at the opportunity to use identical terms from the DDD book, and then keep explaining them with more colloquial terms everybody understands: it's like social sciences all over again (sorry social sciences, but it's what it is) where they invent terms so they'd be more "scientific". Why not simply use the terms everybody understands?

I get the argument that a new language allows for consistency, but it still gets misapplied, because it's the same humans doing the work.

I can't think of a better parallel than SQL-vs-noSQL databases: sure, no-ACID makes a bunch of things simpler, but then every developer has to think through all of the same problems ACID DBs solve, and majority will get them wrong (or maybe even everybody would get them wrong _most of the time_).

[+] Kototama|4 years ago|reply
> 's like social sciences all over again (sorry social sciences, but it's what it is) where they invent terms so they'd be more "scientific". Why not simply use the terms everybody understands?

To be precise probably. Every domain develops a jargon at some point. It can be used to exclude or sound smart but most of the time it just to be precise. Common terms are too much vague / polysemic.

Why do you need words like compiler, linker, dynamic and static types and linter instead of using common words?

[+] arkh|4 years ago|reply
> majority of developers

Jump to coding or architecting because that's their happy place. That's easy, that's what they know so they think that's what they've been hired for.

Shelling some dollars to buy an off-the-shelf solution for some ancillary application? No thanks we think we can do it ourselves and have more control over it. Let's go coding.

[+] latte|4 years ago|reply
The principles listed in the article look like general common-sense design principles. I can hardly imagine anyone designing a system without understanding the problem domain first - and likewise, the problem domain usually drives the underlying models (because what else can they be driven by)? I acknowledge that something the design process strays away from the original domain requirements (especially among the less experienced teams), but that usually feels wrong irrespective of the design philosophy. So the definition of DDD seems a bit tautological.

I would appreciate an explanation of what DDD is by counterexample - i.e. what are examples of non-domain driven design process? Especially, examples of successful or mostly successful projects - i.e. where the disconnect from the problem domain does not feel wrong from the start.

[+] oscarcp|4 years ago|reply
We use DDD at the current company I work in and to be honest, I detest it so much that sometimes it makes me wonder if I even want to continue in the programming space (been at it for 20 years).

Don't get me wrong, DDD has meaning and purpose, but some companies are applying it as a badge to be obtained instead of pondering the question, do you really need to rewrite everything following DDD?

In our case, simple CRUD APIs that in "regular programming" might take a couple 200 line files have turned into unmanageable nightmares in DDD that take you at least a couple of days of really intensive investigation to understand, because it have been divided in more that 25 files that hold 3 or 4 lines of code at most, with so many abstraction layers that it's impossible for the best of us to follow in one go.

Now, you could make the argument "You Are Doing It Wrong(tm)" but since I'm just a drone in this specific scheme and there's no wiggle room for anything (the team is quite inflexible on this) I have to follow it to the letter.

Just giving my two cents, again, not depreciating DDD, it has its purpose but in my opinion, it's for very specific projects.

[+] ToJans|4 years ago|reply
Tactical/technical DDD patterns should only be used for parts of the code where there is a lot of business agility required, so the behavior of your code changes a lot, and you have a tight feedback loop with your business unit.

Your story sounds like they implemented a "technical DDD top-level architecture" (TM), whatever that may be. (I'd assume layers of abstractions coupled with logic spread all over the place, without any added benefit.)

You see this a lot when people read some stuff about DDD, and they start experimenting with the technical/tactical patterns, because this is the aspect that makes most sense to a technical audience.

In reality the tactical/technical DDD patterns should only be applied in the core part of your business (i.e. the thing that gives you a strategic advantage over your competitors.), because that typically needs to change a lot, so having a common language/model with the business tends to be worth the extra upkeep required when opting for more flexible models.

Identifying what the core part is of your business (most likely it's not authentication, billing, invoicing, content management, ...) is one of the more important (and most difficult) aspects of DDD.

[+] mathiasverraes|4 years ago|reply
I'm sorry you're having that experience. DDD is specifically aimed at tackling complexity, as it says on the cover. Part of the problem is that complexity is relative to the observer, how experienced they are in that particular domain, etc. Good abstractions make complexity manageable, bad ones create more complexity. And that's another problem: a domain might be quite straightforward but bad explanations, missing information, bad abstractions, etc can make it seem more complex.

Your colleagues need to remember that DDD is supposed to be applied pragmatically. If the structure causes more navigation work than needed, simplify it. If the problem could be solved with a simple CRUD system, do that. If most of the problem is CRUD, but there's one particularly complex bit that changes a lot and requires a lot of flexibility, isolate that part, so that the simple and complex parts can have a simple integration, don't leak into each other, and can evolve at their own speeds.

[+] danielvaughn|4 years ago|reply
I read a bit about DDD but never really went in-depth with it, like I never read the book or anything.

Instead I just try to absorb the major takeaways that I got from what I've read:

1. Bring in people with domain knowledge to help you understand the expected behavior of the system.

2. Try to establish a consistent language that is used in both verbal conversations as well as code.

I feel like those are good, easy-to-understand principles, and I've never understood why the whole DDD space is taken up by this insanely complicated terminology and theory. It's so off-putting.

[+] ajuc|4 years ago|reply
I signed for a course on DDD thinking it will be about Data-Driven Design. It was about Domain-Driven Design and it's like the exact opposite.

Data-DD is focus on data and keep it simple. Domain-DD is another one of these architecture astronauts fads where you introduce new abstractions and then spend most of the time wondering whether penguin is a bird or a fish for the purpose of your application.

[+] macando|4 years ago|reply
> it have been divided in more that 25 files that hold 3 or 4 lines of code at most, with so many abstraction layers that it's impossible for the best of us to follow in one go.

When you put engineers in charge you get overengineering and when you put managers you get underengineering.

Is there a way out?

[+] jasonhansel|4 years ago|reply
DDD is a wonderful idea and one that I think should be applied more broadly: a deep understanding of the problem domain, shared between tech and product, can greatly improve quality, reduce bugs, simplify communication, and even result in better structured code. In particular, it tends to lead to code structure that follows the structure of the underlying problem domain, which tends to be much clearer than code that just tries to implement features without an underlying understanding of their purpose.

The design patterns and actual implementations traditionally associated with DDD, on the other hand, are quite bad, and tend to lead to Enterprise Software levels of cruft and/or excessively dogmatic use of OOP.

[+] kklisura|4 years ago|reply
Remember when people got offended by the "DDD" acronym? [1] "Good" times...

[1] https://twitter.com/sarahmei/status/1073251153360482304

[+] jdthedisciple|4 years ago|reply
LOL If only people understood the same letters can be used for multiple acronyms https://en.m.wikipedia.org/wiki/DDD

What's even funnier is that none of the acronyms listed there is a soft-porn reference as claimed in the twitter thread.

[+] JohnWhigham|4 years ago|reply
I just don't understand people that insist on bringing their emotional baggage into absolutely everything.
[+] mathiasverraes|4 years ago|reply
The definition is highly summarised, which (like many definitions) makes it only useful if you already understand the concept, and you need a way to remember it. Or the definition can be a framework for explaining it to others, which is how I use it in workshops.

A more real world story of DDD in practice is this blog post:

https://verraes.net/2021/09/design-and-reality/

[+] sovietmudkipz|4 years ago|reply
I am working really hard on how to apply DDD to a video game context, specifically with unity3d. It is a struggle because I think the game creator cultural zeitgeist doesn’t like applying software patterns from ‘outside’ influences, like enterprise software. It is my personal view that the zeitgeist is terribly short sighted and is actually only considering the game client at the expense of the entire software system. (It is also a struggle for me because the video game community appears littered with SEO grifters, and the real experts are very secretive (so different from open source on the web). That is okay because it is fun to synthesize DDD techniques into a new context.

I think of game software as the entire system and not just the game client. That means any backend or infrastructure is a piece of the complex whole.

DDD for backend systems is well understood. The difference is it needs to serve game clients as well as any other clients (e.g. a website to market the game, forums for game related posting, maybe even run logic for chatbot(s)). If you want to expose online services to your game client, the backend system is where you will want to think about what logic to run and what state to persist.

I like DDD for some categories of game client code, not all. There are some simple gameplay elements that are driven from game engine physics and collisions. There are more complex gameplay elements that benefit from more complex domain modeling techniques. Basically allow yourself to write untested/lightly tests components for simple gameplay elements. For complex systems, it may be beneficial to think of unity as concrete implementations for domain specific logic. Model the code in the language of the game system expert and think about how to translate unity runtime events (user input, collisions) into terms meaningful for the domain.

In practical terms, unity game objects represent domain entities and interactions between game objects can trigger domain logic. For example, a projectile game object colliding with a combatant game object is a good place to execute combat service logic, which may trigger domain events (observable behavior) that can then be listened for by subscribers (e.g. a damage UI, a toast notification, or any other unity UI).

This is turning into more of a brain dump but I wanted to send this out into the world since it’s a topic I’m studying heavily right now.

Does anyone have more experience applying DDD to video games out there?

[+] alex_zim|4 years ago|reply
As anything else, a blind application of a technique, paradigm, or pattern, could be horrific. It doesn't matter what combination of capital letters is used. I've done horrific things when I was "doing DDD", until I realised how simple and elegant domain models could be when done right. Forcing people to do something they aren't used to and expect decent results is disastrous in any industry. It's just in software everything can be "refactored" so we are more easy-going with those things.

With DDD "done right" there's no issue with understanding what the code does because it's split into tons of files. It's actually the opposite. But, indeed, it could be a nightmare when applied blindly, or forcibly because of some ivory-tower architect decided to "use DDD" without even knowing what it is. I know as I've been that guy.

[+] bob1029|4 years ago|reply
Yet another overloaded tech buzzword. For me, DDD means 2 things:

1. Listen to how your customer refers to their business and internalize this perspective as if your life depends on it (your career certainly may).

2. Find a way to build your product and communicate about it in similar terms. The methodology should be understood to be domain-specific.

Anything that extends the philosophy beyond these points is making assumptions about your product that really only you and your customers should be making.

The only concrete technical assumption I would make here is that you probably want to at least consider SQL for a few minutes if you are dealing with tons of distinct types and complex, rapidly-changing requirements from the business. If you can find a way to make the business write their own logic/queries in a language they understand, you have discovered the most powerful force multiplier I am personally aware of right now.

[+] jgilias|4 years ago|reply
DDD seems to be one of those things where 'what it's meant to mean' is very different from 'how it's actually practiced'.

Reading about what it's meant to mean, it seems pretty common sense. As often implemented, however, it seems to lead to a lot of accidental complexity and a bunch of dubious usefulness abstraction layers.

I have a theory why this is. It seems that enterprise development as a field have a penchant for methodologies and acronyms. So, whatever silver bullet the enterprise-y shops get interested in eventually gets enterprisified. Be it UML, OOP, Agile, or DDD.

EDIT: I've found this an interesting read that sheds some more light on DDD using counter-examples:

http://media.pragprog.com/titles/swdddf/understand.pdf

[+] jgrodziski|4 years ago|reply
I made this introduction to DDD [0] with my friend Thomas a few years ago. It was specifically intended at developers and to be very practical.

[0] Video of the talk: https://vimeo.com/167722768