On the Relationship between Domain-Driven Design and Domain-Specific Languages
I have always been surprised why the domain-driven design community has so little interest in DSLs. So when I recently saw this post about DDD by Hiral (Vyas) Dave on Linkedin I found myself making this off the cuff comment.?
You guys just don‘t want to use DSLs, right :-)? I seriously don‘t get why. It‘s such an obvious next step for DDD.
So in this post here, I provide a few more thoughts on the relationship between DDD and DSL, mostly shaped by a conversation on that topic that I had with Matthias Bohlen a few days ago, after he saw my comment above.
What are DSLs and why use them?
Let's start with a very brief definition of what DSLs are. The most general definition is that a DSL is a special-purpose programming language for a particular set of problems (aka a domain). That's all. Examples abound in the space of programming, from SQL to CSS to ant's XML. You've all used DSLs.
However, when I talk about DSLs in the context of DDD, I mean something slightly more specific: languages that are used by non-programmers to express the subject matter of a domain. Technically these are still "just" programming languages for a special purpose, but because they are intended to be used by non-programmers, there is a bit more emphasis on learnability and a nice, domain-aligned syntax (textual, tabular, graphical, whatever). And of course the domain they are specific to isn't some programming task (database queries, HTML styling or software builds), but the precise, executable description of the subject matter of the business domain, plus tests for that subject matter.
Why would you want to use such a subject-matter-expert DSL? In many domains there is a lot of very sophisticated application logic that is at the heart of software systems: tax calculation, insurance product definition, telecom pricing strategy definition, clinical trial design, radio telescope observation specs, tachograph rules definition, and so on. This knowledge doesn't come from programmers, it comes from the brains of domain experts. The goal of using a DSL in this context is to enable the people who know about the domain to directly "program" the software system. No more writing prose that is then (mis-)understood by developers and translated into code. I want them to contribute directly. This makes the whole process of getting the domain's subject matter into software so much faster and less error-prone, and also easier to maintain and evolve. If done right, the domain experts feel empowered because they are no longer one level removed from the software system by "just" expressing requirements. There are lots of real-world systems that demonstrate that this works.
Relationship to DDD: Strong Focus on Domain
So here is the first obvious connection to DDD: the strong focus on the (subject matter of the) domain. In fact, let's revisit the definition of DDD from Wikipedia. It lists these three essential characteristics:
I subscribe to that same definition when I use a DSL in a project, and I add a fourth ingredient:
So we don't just represent the domain model as a set of classes and other programming-language-level abstractions (based on DDD's entity + value object + event ... metamodel), but as a separate, tailored language that can be used by domain experts on their own. They are directly and completely for the subject matter by creating models, simulating or running them, and testing them. The models are ultimately deploy into the final software system for execution in the data center or the cloud.
A DSL at the core of the domain
While we're at it, let's cite Wikipedia some more:
Critics of domain-driven design argue that developers must typically implement a great deal of isolation and encapsulation to maintain the model as a pure and helpful construct.
Yes indeed, developers have to build the DSL after analysing the domain together with the domain experts. However, I see this as a massive plus, not as a drawback. Here's why. As software architects, one of our main tools for managing complexity and building maintainable systems is separation of concerns: we try to not mix things that don't quite belong together (loose definition, I know). What could be more important to separate than subject matter (aka domain stuff) from technical stuff (such as robustness, scalability, security and the like)? The complete separation of application logic into models created with DSLs allows both the application logic and the technological concerns to evolve relatively independently as long as the language is maintained together. The language serves as a formal, executable contract between developers and domain experts, improving the collaboration between the two communities. In terms of architecture, the behavior expressed with the DSL represents the innermost layer of the onion or the core hexagon. We use code generation or interpreters to get from the DSL model to an executable code artifact that can be deployed into an application.
领英推荐
More Wikipedia:
Microsoft recommends [DDD] only for complex domains where the model provides clear benefits in formulating a common understanding of the domain.
Agreed as well for DSLs. Developing a DSL is effort, and it only pays if the domain is reasonably big and complicated, and the company's involvement in the domain is long-lived. The domain can definitely evolve -- you just co-evolve the language -- but if your company does insurances this year and drug trials next year, a DSL will likely not pay off. But hey, hardly any company works this way.?
A brief look at other aspects
While this text is not intended as a complete comparison between DDD and the use of DSLs, there are two more points I want to mention briefly:
Another important aspect of DDD is strategic design with its bounded contexts and anti-corruption layers. This aspect of DDD is more or less unaffected by the use of DSLs. It's totally feasible to have different DSLs for different bounded contexts (aka subdomains), or implement some bounded contexts traditionally and use a DSL in only one. It is a good idea to limit the number of abstractions that everybody in the whole organisation has to agree on, not matter whether you use DSLs or not.
The other thing that DDD promotes is a set of predefined metamodels (the term isn't used, but that what it is) consisting of module, service, aggregate, entity, value object, and repositoryplus command, read model, event, policy and such if you use event storming. With DSLs, we often focus on the core behavior of domains, not "just" structure + processes. Expressing the actual tax calculation or drug trial rules with the DDD and event storming abstractions is tough. Which is why with DSLs you don't restrict yourself to these concepts -- you define whatever metamodel makes sense for the domain.
Wrap Up
So, to summarise: In terms of mindset and worldview, I think there are a lot of similarities between DDD and the use of DSLs. In particular, the strong focus on the subject matter of the domain and a joint effort between developers and domain experts to define the language for that domain. DSLs go one step further than traditional DDD in the sense that this conceptual language is then implemented as a standalone language and tool, with which the subject matters can then fully define and test the application logic, separate from programming language source code. Devs write generators or interpreters (and of course implement the language).
I have built DSLs in all the domains I mentioned above (tax calculation, insurance product definition, pricing strategy definition, clinical trial design, radio telescope observation definitions, tachograph rules definition), so the approach works in practice. Whether it fits for a particular organisation and domain of course has to be decided for each case. However, I am pretty confident that there are lots of cases where DSLs aren't used even though DSLs would deliver a significant benefit in productivity and quality.?
So what now? First, if you are interested to learn a bit more, my website is full of essays, papers and presentations on DSLs. I list a few essays that could be useful to follow-on reading at the end of this article.
And second, if you are involved in the DDD community and, for example, are on the program committee of a DDD conference or user group, why don't you invite me to give a talk or participate in a panel discussion to explore synergies and differences between DDD and the use of DSLs further :-) ?
Acknowledgements
Thanks to Sven Grasser and Matthias Bohlen feedback on this text, and to Matthias also for the chat that triggered the writeup.
Further Reading on DSLs
Antifragility Architect / Variety Engineer / Trusted Advisor / Teacher Enterprise Architecture, Antifragility (MSc) / Researcher Cyber Resilience (PhD)
1 年thanks for the write-up and Sharing it.
My main issue with DSLs is that the amount of work to build the associated tooling for a language is often overlooked - you need a way to debug it, and you need a way to test it, and perhaps a way to profile it. You also need to document it. If you skip those things, you are better off using a more general purpose language that has them.
Software urbanist
1 年Just as a remark, DDDAcademy (related to DDD Europe) is offering a course on DDD, Functional Programming and DSLs https://ddd.academy/fp-and-dsls-tom-schrijvers/. Moreover, I found a talk by Eric Evans himself on DDD and DSLs https://www.infoq.com/presentations/ddd-dsl-evans/
Retired from big tech. Not retired from riding the Architect Elevator to make IT and architecture a better place. Have opinions on EA, platforms, integration, cloud, serverless.
1 年I do! https://architectelevator.com/cloud/ddd-technical-domains/ (even references your book)
Software Engineering Consultant ? Professional Photographer
1 年Hiral (Vyas) Dave FYI, Here are some more thoughts on DDD and DSLs.