This blog post is a compilation of my thoughts from two meetups that me and my colleagues at Citerus hosted last fall with the topic Cynefin ♥ DDD. The purpose of the meetups was to explore the relationship between the Cynefin framework and Domain-Driven Design.
To get the most out of this blog post it’s recommended to have a basic understanding of both Cynefin and DDD.
Recognize the title: tackling complexity in the heart of software? Yes, as most people that have come across Domain-Driven Design (DDD) knows it’s the subtitle of Eric Evans excellent original book on the subject. But it actually also says a great deal about how DDD fits into the Cynefin framework and more specifically why DDD is a great tool to manage the complex domain of Cynefin within software development. Read on and I will explain what I mean.
The Cynefin framework does not give a specific answer to the question how to tackle complexity within software development but it offers a framework which is helpful in understanding it. Cynefin makes a clear distinction between the complex domain and the ordered domains. The ordered domains are stable and there is a clear relationship between cause and effect. In contrast, the complex domain is unpredictable and the relationship between cause and effect can only be investigated in retrospect after conducting experiments.
The code that we write as a software developers belong within the ordered domains. A computer simply demands that things are ordered and that there is a very explicit cause and effect in order for it to work. On the other hand, the reality for which we are writing software for is far from ordered. It is complex. This raises an interesting question:
1. How do we map the complex reality into ordered software?
This mapping is often done implicit without putting in too much effort. A big problem with this approach is that the resulting software often becomes a poor fit for the complex reality for which it was created in the first place. The implicit model which the software is built upon will instead of being useful become painful when the software needs to incorporate new requirements. As described by Cynefin it is not a good idea to constrain a complex system without first probing it, identifying patterns and creating constraints from these.
Even if we manage to map the complex reality into ordered software in such a way that the gap between the software and the underlying reality is reasonable small it will probably not stay that way. The complex domain of Cynefin is called complex for good reasons. It changes all the time. A simple interaction within it is all that it takes to make it change. This raises another interesting question:
2. How do we keep our ordered software up to date with the complex reality?
The Cynefin framework tells us to constantly probe the complex world, look for coherent patterns and integrate these into our ordered model. This probing, however, is often absent in the world of software development.
The two questions above illustrates problems which are highlighted when you look at software development through the eyes of Cynefin. These problems are usually not paid enough attention. But within Domain-Driven Design they are put in absolute focus and they are addressed by tackling complexity in the heart of software.
Domain-Driven Design tells us to create a domain model with the purpose to solve a specific problem of the business in the most effective way possible. In the domain model there is no complexity in the Cynefin sense since all concepts are well defined. Thus, the domain model resides in the ordered domain of Cynefin. But the model still originates from a complex reality and in order to create it we have to create explicit terms in the ordered domain from ambiguous ones in the complex domain. Domain-Driven Design calls this process knowledge crunching. Going back to the first question:
How do we map the complex reality into ordered software?
Knowledge crunch the complex reality and create a domain model.
But to tackle the complexity of the real world it is not enough to create a domain model and keep it static. It is very important to constantly challenge the domain model. This is a core practice of DDD and is done by exercising the model using techniques such as scenarios and code probing. This gives you feedback about how effective the model actually solves the intended problem. Going back to the second question:
How do we keep our ordered software up to date with the complex reality?
Constantly exercise the domain model by probing the complex reality and incorporating useful knowledge into the model.
A valid question at this point is why it isn’t enough with a model? Why do we need a domain model? I agree, you will get many of the benefits in tackling complexity by using a model. The thing that makes a domain model shine is that the possibilities for knowledge crunching and probing are so much greater. The reasoning behind DDD is that the complexity of software development is not technology, it is understanding the domain and turning it into working software. Doing so requires not only developers, but also domain experts. If we use a domain model the domain experts can contribute to the knowledge crunching and probing. Not only does this include feedback from domain experts which otherwise would be lost, but it also make the feedback loop from the complex reality into order software much faster.
In conclusion Domain-Driven Design is a great tool for handling the transition between the complex domain and the ordered domains of Cynefin within software development. It is a great tool to tackle the complexity in the heart of software.
How do you tackle the complexity in your software projects?