5 ms·
Why I don't do Domain Driven Design (2018)
- upghost 2y agoI 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!
- onli 2y agoThere 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 2y agoI 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.
- onli 2y agoFair enough, the comment certainly did. But the message or question was more supposed to be about that a simple crud app does not need a big methodology anyways, and that DDD isn't meant for that in the first place (iirc building a simple crud app is a reason not to use DDD, at least in one of the main books). I'm aware that sometimes simple software can have a lot of value.
- motorest 2y 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.
- onli 2y agoNot talking about DDD here, but the linked article describes this as his alternative approach.
- d0mine 2y agoSomewhat 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 2y 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 2y agoIn 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
- epolanski 2y agoIt 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.
- pyrale 2y agoThat’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 2y agoYour 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.
- pyrale 2y agoThe same is true of every interesting concept in dev, unfortunately: design patterns being made into a pokedex, agile into an inflexible process, hexagonal arch into a guideline for project directories’ names and layout, metrics into goals, etc.
- upghost 2y agoCome 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.
- 2y ago
- namaria 2y ago"Steel man" doesn't sound like the opposite of "straw man". It just sounds like a more resource intensive version.
- that_guy_iain 2y agoDomain 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.
- jeroenvlek 2y agoIn the average organization, if you're not talking to other departments then, almost by definition, you're also not doing DDD.
- that_guy_iain 2y agoIt'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.
- bvrmn 2y agoDDD 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 2y agoThere are no such ceremonies in DDD land. At worst you have ceremonies around organizing layers but that's a pro not a con.
- Lapalux 2y agoThis is a nice summary. I do devops/infrastructure for a SaaS company that use DDD and this was helpful for me to refresh my knowledge of terms and concepts
- wesselbindt 2y 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 2y agoGiven 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 2y agoI 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 https://www.youtube.com/watch?v=hYAuR5bkIlQ
- JackMorgan 2y agoI'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.
- xbar 2y ago"...I ALWAYS start writing code AFTER I have designed and constructed a properly normalised database..." I found success with this practice, too.
- epolanski 2y agoI want to try it, but I don't fully buy it. It doesn't seem to fit the reality of most projects I've worked where you have the luxury of so much analysis, trial and well defined requirements. My approach in development is in general to give a working prototype as soon as possible to the relevant users and stakeholders and keep refining those. The con of my approach is that then user think the project is in a much advanced state than it is.
- dijksterhuis 2y agoi usually value component diagrams more than normalized databases plans etc — not every system uses a database! chuck some blocks into diagrams.net, sketch out the information flow at a high level, then go implement it. i find it often helps factoring the code a bit earlier, meaning the prototype looks … less like a prototype in the code =p also can be faster to move around blocks in a diagrams.net diagram than it is to refactor large swathes of the underlying code related to those blocks.
- namaria 2y agoI have found that the "ship something then iterate" approach to software development can get stuck in local optima without a clear path to get out when it gets flooded by unforeseen problems. Then it becomes a maintenance nightmare. But by then the original developers will have moved on with their careers or they are just happy chugging along with the mess they've created because they're not competent enough to know better.
- tasuki 2y agoMe too. I worked with some people who thought the database was an implementation detail. This created quite a lot of friction. I hope it was a learning experience for all of us.
- airstrike 2y agoOr, you know, just take inspiration from The Elm Architecture.
- naurupatel 2y agoI love this. DDD is a great tool for the right job. Unfortunately I've often seen it used for strange use cases that don't fit.
- noisy_boy 2y agoThis 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).
- agentultra 2y agoI 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.
- giancarlostoro 2y 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.
- dventimi 2y agoI 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 2y agoThat’s cool! I enjoyed the book and many of his talks and writing elsewhere. You never know what’s going to stick.
- mjr00 2y agoDDD 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 https://en.wikipedia.org/wiki/Anemic_domain_model
- dvydra2 2y agoWell said! Designing from first principles is how we get ahead and outcompete those who are stuck in the past.
- globular-toast 2y agoSo 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.
- deleted 2y ago[deleted]
- lerp-io 2y agothere is no definitive rulebook for anything in any field. it's just whatever one thought was best at the time until someone refactored or figured out a better solution, product, etc.
- rockyj 2y agoThis 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 2y 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 2y agoCQRS 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.
- mediumsmart 2y agoI know that everybody else is wrong but I am not going to blog about it because people might misunderstand or treat it as gospel which is both wrong but I said that already.
- karmakaze 2y agoI really appreciate the summary of DDD points in a table. It makes it easy to see which points still make sense and most which don't. > I have been designing and building enterprise applications for four decades, with the last two being dedicated to web-based enterprise applications using an object oriented language [...] I don't see any applicability of this to my current work as I exited enterprise app dev decades ago. I still use OO languages but not in an OOP way.
- Degorath 2y agoBit late to the party, but it looks like the author created a "framework" that allows for extremely rapid development of the simplest kind of CRUD app. Everything is fine and dandy as long as nothing needs to change, or if it needs to be changed, then the changer is the author themselves. I applaud the author for their intellectual pursuit, but I don't think it's fair to compare this to codebases where one does not simply pass the POST request body into the database.