To main site
Back for more posts
Technical
Software
Writings
Share:
4 min read - 608 words
Date published: 7-Apr-2023
Date modified: 7-Apr-2023

Monolithic and Domain Driven (and Microservices) designs

For a detailed deep dive on each pattern, check out https://microservices.io/patterns/monolithic.html and https://martinfowler.com/bliki/DomainDrivenDesign.html.

If you have been involved in software engineering for the past couple of years, you have probably heard of these concepts, along with microservices architecture. Recently, my team faced a challenge to reinvent our operations platform, and many of us, myself included, rose to the challenge and proposed a new system redesign. When I presented my solution, I received some pushback due to the perception that it was monolithic, which I strongly disagreed with.

While I can't disclose the details of the design (due to confidentiality and whatnot), I think this might be a good time to reflect on my understanding of these designs. There isn't one pattern that fits all, and they all come with trade-offs. For example:

  • If you need to focus on development and deployment speed, a monolithic design can be useful. However, a failure might bring the entire system down.
  • To focus on reducing the blast radius in failure scenarios, microservices can come to the rescue. However, if not structured carefully, you may lose a great amount of traceability or fall into the trap of a pseudo-monolith via a complex dependency model (check out this post https://sheepcode.substack.com/p/devlife-5-microservice-hell).
  • A good balance of both might be domain-driven design. However, this requires us to have a good understanding of the business context before we can pursue it.

The contention point here is separating between monolithic and domain-driven architecture. Often times, folks tend to identify monolithic system by the amount of responsibility/scope it manages (good place to plug the SOLID principle https://www.freecodecamp.org/news/solid-principles-single-responsibility-principle-explained/). This is a flawed approach as it does not take into account the core nature of the two designs

  • Monolithic relies on coupling: component irresponsibly dependent on each other and communicate without a well defined interface. A consequence of this is when you introduce an extension feature, you often find yourself changing things in multiple places
  • Domain-driven relies on cohesivity: components are independent but works closely with each other. Contrast to microservices, components focus less on re-usability but more toward a specific problem scope.

To get better at identifying these architectures, I suggest to find answer to these few questions below

  • On deploying change, does the entire system need to be updated?
  • When extending features, can you look at the high level design and have some sense of what system needs to be updated?
  • Do components communicate through a well-defined interface, or are they just recklessly call each other

The reason my design was called out as monolithic was because it took the complete scope of 3 different workstream and 2 different teams within my org. This is what good domain-driven design supposed to do: less people can do more stuff. In the end, I was able to rally engineers, my manager, and my skips. My proposal was able to triumph and it actually one of the key projects for my promo. I guess another hidden lesson here is to understand and manage the political game as well.

It's important to keep in mind that implementing any of these design patterns requires a significant amount of planning and consideration. It's not as simple as just choosing a pattern and applying it to your project. You'll need to carefully consider factors such as scalability, maintainability, and fault tolerance, as well as the specific needs of your organization and your development team. With that said, if you take the time to carefully evaluate your options and choose the right design pattern for your project, you'll be well on your way to building a successful and effective system.