Readit News logoReadit News
mjr00 · a year ago
DDD is one of the most misunderstood "patterns" I've encountered. I started my career in the late 00s, and Evans' DDD/Fowler's PoEAA were treated by gospel as some, and I couldn't quite understand why. With years of experience, I now get it: software being built in 2003 was a lot different than software today.

DDD/PoEAA implicitly are about building long-lived, stateful thick clients -- i.e. a Java/C++ desktop application, because that's what people built by default in 2003. In the past 22 years, things have changed. The Bezos "API mandate" has either explicitly or implicitly been adopted by many organizations. Front-ends are much more likely to be websites/Chromium operating with stateless HTTP requests, instead of long-lived desktop applications. (React has "won" as the default JS framework over the past 10 years, and that has its own set of architectural patterns which don't mesh with DDD.) Backend software is built with a cloud-first mentality: servers can fall over at any minute, the application should scale up by adding more servers, etc...

All this leads to a much different approach. Statelessness is nonnegotiable, since you're dealing with stateless HTTP/GRPC requests that expose most or all of your functionality. The "anemic domain model"[0] is derided as an antipattern by DDD, yet it's the most sensible approach for dealing with objects that get loaded and disposed of with every request. Complex ORM schemes and patterns like "unit of work" are fine when dealing with small amounts of data, but break down when you start needing to care about e.g. splitting transactions into smaller chunks because writing 200,000 rows in a single tx is a bad idea.

I don't think DDD is useless, but its application is much narrower than advertised. It's a shame that even today people are still being taught from DDD as if it's the "right" way to code when for a large amount of modern software it's a terrible fit.

[0] https://en.wikipedia.org/wiki/Anemic_domain_model

globular-toast · a year ago
So are you saying nobody needs to write "small amounts of data" any more and we should treat everything like it's a 200k row write?

I don't get how an an anaemic data model makes more sense just because of database persistence. You save/load the data. It's completely irrelevant where the logic is.

mjr00 · a year ago
> So are you saying nobody needs to write "small amounts of data" any more and we should treat everything like it's a 200k row write?

Not at all. As I say, DDD isn't totally inapplicable now; if you're writing a small, stateful application with no need to expose functionality externally, it can be a good fit. But you're a lot more likely to be dealing with data volumes that require 200k row transactions, or a requirement to expose functionality and data via APIs, in 2024 than you were in 2003. The scale of software has gone up significantly in 20 years.

> I don't get how an an anaemic data model makes more sense just because of database persistence. You save/load the data. It's completely irrelevant where the logic is.

DDD largely treats the database as an impure, imperfect implementation detail that needs to be worked around, rather than an essential part of the application. I've seen examples of creating "entities" called like `UserTransaction` in order to retain the "purity" of using OOP for everything. There's also a lot of literature where people suggest using database CASCADE to deal with updates/deletions which, IMO, is awful and outdated. It's totally ridiculous and is just creating more work in order to avoid the bogeyman of (gasp) stateless procedural programming that was very out of fashion at the time DDD was written.

dvydra2 · a year ago
Well said! Designing from first principles is how we get ahead and outcompete those who are stuck in the past.
upghost · a year ago
I think I learned more about what DDD is from this article than most of my books on DDD. This is the right way to do a critique -- it starts out with an excellent Steel Man understanding of DDD and proceeds from there.

I guess they don't make em like they did in 2018 anymore!

pyrale · a year ago
That’s not good news, because this article is dead wrong about many ddd concepts. For instance, the very first list item:

> DDD is against the idea of having a single unified model

Is wrong: DDD is not against the idea of an application having a single unified model.

Bounded contexts exist to help you understand the organization, and, specifically, that different people may use the same word with a different meaning. But if your application serves a single group in the company where definitions are shared, there is no reason for your code to leverage multiple bounded contexts, and their existence may be limited to a footnote in the project’s business glossary doc.

epolanski · a year ago
Your counter opinion kinda confirms the issues with stuff like DDD being consistently open to interpretation.

Not surprising, it lacks clear and rigorous definitions and almost everything is example-driven.

It's like lacking both the rigour of academia, and the practicality of seasoned engineers at the same time.

upghost · a year ago
Come come now. That's the very first bullet point of the article. The article did a very good job of giving DDD its due. I don't think it's fair that the article went out of the way to define what it meant by DDD in a Steel Man fashion and this response attacks the first and easiest to attack point of the article in a Straw Man fashion!

In fact, the comment I made wasn't even about DDD, it was more about how I appreciated the construction of the argument. Agree or disagree (I happen to be a fan of DDD) I learned a lot from the article and I wish more articles were constructed like this.

epolanski · a year ago
It doesn't help that DDD like most OO-related theory is very poorly defined.

It's also something that pushed me towards functional programming, I could finally understand concepts by understanding their definitions.

onli · a year ago
There are some things in there I did not exactly get. Mainly, if every class has its own table, and database operations are all so similar, is the software produced not only a collection of very simple mechanical operations? How could there be any value in that?

But there are good things there - data first for example, and the correct identification of interfaces - which will help avoid useless indirections often misunderstood as abstraction.

rowanG077 · a year ago
I think you are conflating technical complexity with value. There are a ton of things where a simple app you describe brings value. They even have a specific name CRUD apps.
motorest · a year ago
> Mainly, if every class has its own table, and database operations are all so similar, is the software produced not only a collection of very simple mechanical operations? How could there be any value in that?

DDD does not have the concept of a table or database, let alone requires it. There's some degree of confusion expressed in your comment.

In a somewhat simplistic explanation, Domain-Driven design focuses on creating a model of the application domain, and with that define the necessary and sufficient operations that implement your requirements. All your operations are implemented in terms of your domain model. The tricky part is putting together a domain model that's consistent and doesn't allow the system to generate invalid data or be left in an inconsistent state. This leads us to the concept of root entities, and on top of them use aggregates to express transactions that involve multiple entities and values.

d0mine · a year ago
Somewhat unrelated: Value has nothing to do with complexity, effort on your part, etc. Imagine you have a customer who needs X, you can do it in Y days today but tomorrow another customer might require X’ (something very similar to X) and now you can deliver it in Z << Y days (eg by reusing a framework developed for X). Value of X, X’ to the customer may be very similar despite your effort Y, Z drastically different (junior dev shouldn’t charge more just because it might take them longer).
epolanski · a year ago
> is the software produced not only a collection of very simple mechanical operations?

In the context of mostly crud operations unsurprisingly yes.

The value lies in knowing where and how you'll find the relevant pieces you need to touch to e.g. add new features or extend business rules, without ending up putting business logic in the wrong place (such as misplacing it in a service responsible for communicating with the db e.g.).

Joel_Mckay · a year ago
In general, I observed a few programmers that are keenly aware of their skill set, and tend to complain loudly about systems that hold people accountable by colocating their bad workmanship with their area of responsibility.

The secret of bolting on a good AMQP pattern is embedding signatures, GUID, UTC time, and expected state pre-conditions. The notion a problem domain even fits into a monolithic structure is laughably naive.

Usually, toy naive designs devolve into a dynamic object storage model on SQL, and it is ridiculously silly in this age.

Best regards =3

namaria · a year ago
"Steel man" doesn't sound like the opposite of "straw man". It just sounds like a more resource intensive version.
agentultra · a year ago
I found the original book to be rather dry and difficult to read. Like most books on software design. It’s full of hand waving and folk tales.

However I think there are some good nuggets in it that are worth taking away and using. The idea of ubiquitous language is useful. The best software teams I’ve worked on were great at talking with business users and customers. A ubiquitous language helped us avoid “programmer speak,” where we talked using names for things nobody had heard of but us and nouns and concepts nobody else understands. It allowed us to communicate more precisely and avoid mistakes throughout the process.

Good article. There’s always going to be counter-points and folks who prefer one way over another. I think there are some useful nuggets in this one too.

dventimi · a year ago
I was friends with Eric at the time (we've long since lost touch) and he asked me to review a draft of his book. I didn't have the heart to tell him it was unpublishable gibberish. The joke's on me, obviously: turns out, it was very publishable gibberish.
agentultra · a year ago
That’s cool! I enjoyed the book and many of his talks and writing elsewhere. You never know what’s going to stick.
giancarlostoro · a year ago
> A ubiquitous language helped us avoid “programmer speak,” where we talked using names for things nobody had heard of but us and nouns and concepts nobody else understands.

This is part of Domain Driven Design btw. I fully agree with this too. Makes it easier.

noisy_boy · a year ago
This seems to be more like hair-splitting on the below broad setup that I think is fairly commonly followed (atleast in Java CRUD world):

1. A model represents a record of a table (or a view). If a validation on a field is as low-level as null/not-null, it is better defined at a database level. Additional business logic related validations (that solely require the properties of the model as input), can be part of the model.

2. A repository provides facilities to interact with the database for either returning or creating instances of model and associated actions. Basically db-related actions live here.

3. A service can provide ways to perform operations related to the model with the help of the repository. E.g. fetch all records with a given area code.

4. For business-logic/workflows that span multiple models, higher-level services can invoke multiple lower-level services to orchestrate the workflow.

5. Controllers host the user-facing request/response related methods that invoked the higher-level services.

There can be variations of this with their pros and cons but this approach has worked well for me (mostly using Spring Boot).

that_guy_iain · a year ago
Domain Driven Design makes so much sense. But, in my opinion, it's generally just an excuse for people to show how smart they are. They often don't talk to any other department, they'll come up with excuses for this and refuse to admit that they're not doing DDD. They'll claim they're doing "tactical DDD" or some other name. These same people will force everything to be immutable even tho it's clear under DDD that entities are in their nature mutable. It's often a collection of doing things that aren't what they're meant to be.

If you're actually talking to other departments and have a very tricky domain I fully believe that DDD can solve some major problems. If not, I think you just want to show off how smart you are. And if you want to show me how smart you are do it by solving problems for people. Especially the problems that others can't solve.

bvrmn · a year ago
DDD is simply a common sense. Every sane project models domain in domain terms and has layers. There is no need in ceremonies around file structure and method names.
epolanski · a year ago
There are no such ceremonies in DDD land. At worst you have ceremonies around organizing layers but that's a pro not a con.
jeroenvlek · a year ago
In the average organization, if you're not talking to other departments then, almost by definition, you're also not doing DDD.
that_guy_iain · a year ago
It's not almost it is exactly the definition. The key thing about DDD is ubiquitous language, which is everyone using the same language. And learning things from the domain experts who are in other departments. If you're not talking to other departments you can't be using the same language as them. Nor can you learn from the domain experts. Nor even ensure that the domain flow maps the same as the company. DDD and BDD are fundamentally about talking to people. But that's the hard part so people skip it.
wesselbindt · a year ago
(2019)

I skimmed the article a bit, because it's structured in a strange way, and I couldn't quite find my footing. Then I came across the phrase

> it was everybody else that was wrong

in a section on composition vs inheritance. I know that it's a completely superficial thing to say, but I find it hard to take texts that sincerely use this phrase seriously.

onli · a year ago
Given the state of programming, think javascript frameworks on the Web or always failing overly complex enterprise software, statements like that can easily be just spot on.
PittleyDunkin · a year ago
I assumed that this was intentionally a signal that you shouldn't take this too seriously and a reference to this Simpsons clip: https://www.youtube.com/watch?v=hYAuR5bkIlQ
rockyj · a year ago
This article provides a lot of validation from my own experience. I was always weary of DDD fanatics, I always thought I was not bright enough to understand statements like -

- In domain-driven design, the Domain layer is one of the common layers in an object-oriented multi-layered architecture.

- DDD is against the idea of having a single unified model; instead it divides a large system into bounded contexts, each of which have their own model.

I do not know what these mean and I have found no real good explanations. In my 20+ years of experience I have not seen any problem which is solved elegantly with DDD based development and/or CQRS etc.

My simple rule of new tech / random things such is these is - what is the adoption rate and what are the major success stories. With technologies like RoR, React, Spring Boot, Kotlin etc. it is easy to see the reason for their adoption and success. I have heard no such stories for DDD. In fact, I have found the developers which advocate these have been the hardest to work with (rich on theory and opinion and poor in actual written software).

F-W-M · a year ago
> DDD is against the idea of having a single unified model; instead it divides a large system into bounded contexts, each of which have their own model.

If you have a large system it makes sense to divide it into smaller independent pieces. If you have a (micro)-service architecture you have distinct services, in a monolith you might have modules.

It is a hard problem to know where exactly the boundaries between services or modules should be, in any case DDD calls the things that make sense to decouple bounded contexts.

mrkeen · a year ago
CQRS is great, (but I've not heard it linked to DDD before this article.)

If you have an SQL schema and your domain is money, some numbnuts is going to get the rounding wrong, accidentally calculate with floating point, forget to store currency, forget what the minor unit of each currency is, mix up credit/debit, and/or use a negative sign when there's an agreement not to.

You won't find out about the mistakes until after you've been running in prod for a while. And fixing the code won't fix the problem, because you only find out about the bad code after you've already produced bad data. But you still have to struggle to fix the bad code anyway. Use migrations to introduce new columns, while the system is running, etc.

What if instead of everyone updating one central table in-place, they just put their updates into some persistent queue, in some loose json format? If you were to keep that data around, you could at any time create new SQL tables and populate them from the source data. You could even afford to get it wrong a bunch of times, because you can throw away the tables.

globular-toast · a year ago
Event sourcing? I thought that was a very DDD thing.
JackMorgan · a year ago
I've read several books on DDD and was on a team that fully bought into the idea and attempted to implement it for five years.

After all that, I think the concept of a ubiquitous language is excellent. Everyone should standardize on a common set of vocabulary. We even took it so far as to have a dictionary of our business domain terms. It's so obvious in hindsight that it seems completely foolish to do anything else.

The rest of the book is basically just one guy's preferred way to organize a CRUD codebase. You can use his preferred terms (entities, repositories, value objects) and put things in the "right places" based on how he really liked to organize the codebase on this one job he did. After trying sincerely to follow this book for five years, I now think this has very little value. I don't particularly care what he thinks is the difference a service and a repository. When we had a need that wasn't obvious from the book, we'd sit in on countless meetings of people arguing the definitions while quoting the DDD book like it's a sacred text. Endless bike shedding about one guy's favorite way to organize a CRUD app isn't a high value use of a team's time. Neither is spending weeks renaming and moving everything to match the perfect terms.

We bought into the idea that if we followed this guy's favorite organization, everything would be better. It wasn't. We spent a huge amount of time reorganizing 1.5 million lines of c#. I don't think we ever even gained a week back of that time. It was a huge waste of time for what? To feel good that we were following some book? We didn't reduce or remove any bugs. We didn't find it magically easier to add new domain logic, if anything it was harder because we had to debate every feature to ensure it was designed "correctly" according to the will of Eric Evans.

For example, look at this snippet from the article

> "Objects outside the aggregate are allowed to hold references to the root but not to any other object of the aggregate. The aggregate root checks the consistency of changes in the aggregate."

Imagine trying to read an entire book filled with this kind of language. Lots of new terms, special rules, and vague reasoning. It's perfect for creating an environment of religious debate.

Today I think that books (Riting Software is another) that just prescribe an organization are a waste of time. They promise benefits for just using new special terms and putting logic in the "right place" but then don't deliver. It's just one dude's preferred names for things, not a magic recipe.

A better option for learning architecture in my experience is books like "Structure and Interpretation of Computer Programs" that teach excellent fundamentals. Data structures, algorithms, functions, state lifecycles, asynchronous code, dynamic code generation, and DSLs are far more valuable and people rarely give them enough time. Once I got very comfortable with those fundamentals did architecture appear to me as just the same concepts repeated at a larger scale. Drilling fundamentals was highly valuable, and I wished I'd spent more time on those early instead of reading books about DDD.

quercusa · a year ago
> I think the concept of a ubiquitous language is excellent. Everyone should standardize on a common set of vocabulary. We even took it so far as to have a dictionary of our business domain terms. It's so obvious in hindsight that it seems completely foolish to do anything else.

I started doing this after working on ANSI/ISO standards. It feels like a hassle until there's an 'ah-ha' moment where (e.g.) everyone realizes that what Group A called 'foo' was what Group B thought was a reference to a 'foo', and not the thing itself.

dvydra2 · a year ago
Agree 100%. Its totally demoralizing to show up at work where folks are unable to hold a discussion from first principles. I've worked with Eric Evans. He is a brilliant engineer and I appreciate the effort he took to put his ideas into a book, but when I show up to work I expect the team to be empowered to chart its own course based on its particular context.
globular-toast · a year ago
Hmm... DDD is specifically not about building CRUD apps. If your business is literally creating, read, updating and deleting records, and that's all you talk about all day with your customers, then you don't need DDD. DDD is about building software for businesses that actually do stuff. So your vocabulary would include words like ship, publish, accrue etc and nobody ever talks about "updating records" ever. I maintain a system for inventory storage and tracking. The users want the system to tell them where to put inventory, they don't even know or care about the database.

SICP is more general and definitely includes the really powerful bits, namely using abstraction to build higher-level languages (like DDD's domain model). DDD is more of an opinionated way to build business software specifically.

zeendo · a year ago
I'm tempted to guess where you were that this occurred (A large payroll/benefits software company - maybe even the ultimate one...)

But then again this story has probably happened thousands of times...

datavirtue · a year ago
DDD is just a sign that you should run. I was present for a system rewrite using DDD. We had developers duplicating entire models in separate databases and all number of dumbass shit. It resulted in a system that was very difficult to understand and support. Someone has to define the domains, get it wrong and the entire thing is a mess. DDD belongs on the scrap heap.
wesselbindt · a year ago
> We had developers duplicating entire models in separate databases and all number of dumbass shit.

That's DDD?

rr808 · a year ago
> It's just one dude's preferred names for things, not a magic recipe.

Pretty much most frameworks can be described like this. I think its worth choosing one when you start then sticking with it. Like you say, refactoring down the road is a huge effort and not a huge benefit.

Cthulhu_ · a year ago
> After all that, I think the concept of a ubiquitous language is excellent. Everyone should standardize on a common set of vocabulary. We even took it so far as to have a dictionary of our business domain terms. It's so obvious in hindsight that it seems completely foolish to do anything else.

See, while I have very limited experience actually writing code in DDD style (and at the time, because I hadn't read the book or followed any course, terms like "aggregate" were pretty alien to me), I can really see the benefit of the DDD approach to mapping out and defining a problem space or company; ubiquitous language, bounded contexts (a "customer" may be different depending on whether you ask frontline customer support vs corporate support), and just mapping out the flows and processes of how a company or part thereof are just super valuable. Because a lot of the ones I've worked for as a consultant (read: code robot for hire) seem to rely a lot on a number of key people or departments that have this knowledge in their head, while IMO it should be a central "database" of the One Truth that everything else in the company follows from, including software.

And if the processes and requirements are clear, then software will follow, whether they do DDD practices or not.

epolanski · a year ago
Me too, while I hated DDD at the beginning due to how terribly and poorly defined it is, it's really a good fit in both OOP and FP land.

I have very little doubts on how to traverse and what/where to touch in a DDD application.

I know where I extend the logger, and where do I add business logic without much doubt.

Everything ends up well organized. I have to say I'm also lucky to never have worked with unpractical engineers fighting over exact boundaries when applying DDD something that seems to be plaguing some other users in the comments.