I keep saying that design and programming are sides of the same coin. This means that both are required to develop a proper product but it also means that they are different . As the name implies, Domain Driven Design is design, therefore it’s not programming. And this is quite important because programming, as a mindset, can be and it is an obstacle in doing DDD properly.
First and foremost, DDD means strategic design aka high level design where we don’t care about implementation details like code, database, monolith/micro services etc. Sure, DDD has tactical patterns which help us in writing the code, especially doing low-level (object, function) design but the DDD tactics are still higher level than code.
The power of DDD (the strategic part) comes from understanding the domain i.e understanding the business mindset, language and solutions. It’s not about coming up with solutions (the programmer mindset), but understanding how the business implements its own solutions. When we do Domain modelling, we open our eyes, ears and brain and we learn about the business concepts and behaviour. It has nothing to do with code. At this level, concepts are just a name(not a class) and behaviour is how the business uses those concepts (not a method/function).
It’s also important to understand the domain relationships between the concepts. Those aren’t RDBMS relationships (one to many), nor OOP relationships (is a or has a ). It’s not about applying programming principles, it’s not about identifying programming relationships (inheritance, composition) to be written in code.
For example:”A table has 4 legs”. In domain speak this might mean that the “Table” concept requires 4 legs in order to be a valid concept for a specific use case. It’s not about a Table class which has a “Legs” property, although it might be a valid way to implement it in code (but at this stage we aren’t concerned with writing code, we care about understanding how the business sees (defines) that concept in a certain scenario) . Another example: “A person has a hat”. Applying the programmer mindset is wrong, you’ll end up with a class Person that has a property “Hat”. But from the domain point of view it might mean that “a person owns a hat” and/or “a person is wearing a hat”. Domain relationships != object/table relationships. Domain language != programmer language.
The whole point of the DDD strategic design is to identify the business concepts, their constraints and the business behaviour (use cases and business rules), it’s not about writing code i.e designing class diagrams or worse, databases. Sure, we need to implement all those in code (our final objective), but first we need to have a very thorough understanding of the things, only afterwards we begin writing code. Basically we need to become domain “experts”. And the programmer’s mindset is an obstacle in our way.
Even the DDD tactics are higher level than code. You can think of them like this: strategic design is the highest level and it involves learning the domain mindset. Next we’re using the tactics (aggregates, entities etc) as an intermediate step, where we’re trying to focus and group together the relevant concepts and business behaviour aka business rules, for a specific use case. Only after that we can go implementing things into code, after you know the aggregates.
The DDD tactics are themselves design abstractions, not implementations. The aggregate is a group of concepts (not objects!) and business rules, required by the business process to maintain its consistency when you want to change things. In practice, you have a bunch of names and rules. Those can be implemented by code using your favourite approach (OOP, FP or both). Always, the actual code is an implementation detail (this is the programming part), but we need the proper high level design (concept abstraction) first.
The whole point of DDD is to help us coming up with a model that mimics how the business looks at the things, how the business works in the real world. This will allow us to implement business changes faster, because the code itself is designed (modeled) according to the business mindset (efficient or not). When the business change in a certain way, the code just follows. If we design things programming driven, it will always be a mismatch between the real business model and the coded model, resulting in slower, more complicated changes. Yes, your code could be of the highest technical quality and your algorithms the most efficient, these don’t matter if any change required by the business means you have to resort to patching, cutting corners, technical debt or delivering value very slow.
We don’t build software for the glory of technology (most of us anyway), we build a product that delivers value to its stakeholders. That’s why in DDD, business (domain knowledge) comes first, code comes second. Rushing to write code usually means ending up with an improper domain model which on the long run becomes more and more complicated and harder to maintain. I cringe when I see people asking how to code things in DDD, it’s not about the code, it’s not about learning a new magic recipe, it’s not about being a (better) programmer. That’s why, when we’re doing DDD (and high level design in general), we should forget we are programmers. The programmer mindset of finding solutions is an impediment when trying to learn how an existing system (a domain) works. The best quality of a DDD practitioner is listening, not problem solving.
P.S: Obviously, all the good modelling and design is useless with a crappy implementation, but the point here is: understand business first, understand business second, write code third.