Reducing Complexity of Software with Domain-Driven Design and Microservices
What makes software complex?
“For me, the definition of complexity comes from the number of things you should keep in mind when working on a software project,” said Sergey Matyukevich, Senior Cloud Engineer at Altoros, during a recent meetup in Austin, TX.
Although microservices were the ultimate topic that Sergey covered in his presentation, he cautioned attendees “not to think microservices first.” Instead, Sergey suggested to start with the Domain-Driven Design (also known as DDD).
Domain-driven design has now been with us for more than a decade. The term was coined by Eric Evans, who wrote the seminal book on the topic in 2003, entitled “Domain-Driven Design: Tackling Complexity in the Heart of Software.”
The book, by the way, is still readily available.
His key insights at the time were to make the software fit the project, i.e. the domain, and establish a shared vision and “vocabulary of design” within the team. (The latter becomes relevant to the use of what’s known as ubiquitous language, and is discussed near the end of this article.)
Addressing complexity with microservices
Since that time, with the emergence of cloud computing and the widely distributed architectures that often go with it, complexity has increased by at least a magnitude. Thus, the proper way to go about DDD is more relevant than ever.
Sergey outlined several ways a project can be considered complex today: multi-system, multi-platform, working with legacy interfaces, a need for data caching, and the use of several coding methods. Add to that the need to scale, often logarithmically to hundreds of thousands of users and beyond. He illustrated this basic overview in the following slide:
He recommended decomposing an application into smaller pieces as the proper way to go about things, and illustrated the idea of decomposing layers, then transforming the resultant modules into microservices:
He also stressed the importance of loose coupling, that fundamental approach to service-oriented architectures (SOA) that begat the modern era of complexity during the timeframe of Eric Evans’s book:
A nicely detailed discussion of modules can be found here.
Sergey illustrated how to identify modules based on physical layer separation:
And then on layer abstraction:
The modules should also be thought of as existing within bounded contexts—a topic undertaken briefly in the module discussion link above, and illustrated by Sergey thusly:
Then it was on to microservices, which can be formed from modules (i.e. the modules transform into microservices when there is a need to scale modules independently).
Ubiquitous language is the other key aspect of successful DDD, and Sergey provided some examples as follows:
Complexity is with us as a permanent part of the cloudscape. It can be thought of as strategy or perhaps even philosophy rather than code monkeying. Successful app development and deployment in multi-platform cloud infrastructures behooves a DevOps culture and commitment to continuous integration.
As Sergey demonstrated, recognition and practice of a few key fundamentals helps organizations to master the ABCs of DDD. At the same time, while domain-driven design and microservices reduce the complexity of software, cloud apps may still become more complicated—however, this time, in a more intelligent way.
Want details? See the slides!
Related reading:
- Addressing Complex Software Systems with Microservices and CI/CD
- PaaS vs. IaaS for Microservices Architectures: Top 6 Differences