---
# System prepended metadata

title: On Decomposing Monoliths & Modernizing Software

---

# On Decomposing Monoliths & Modernizing Software

*A smart colleague posed a very interesting question that prompted this essay.*

> Why Does App Modernization Result in so Many Microservices?

I am going to visit this question from first principles.  Our industry likes to move ahead in whipsaw fashion. From monoliths to microservices, from microservices to functions, and so on. Microservices based architecture provides an excellent way to reduce cognitive load on developers and align business capabilities/domains with software. Model driven approaches like Swift motivated by Domain Driven Design (DDD) are used to break down monolithic and complex systems.

**As humans we suffer from a number of biases. Event Storming (ES) - a group human collaborative activity - reinforces our observer-expectancy bias where the cognitive bias of the participants causes the participants to influence the outcomes in the direction expected i.e. additional domains/services/sub-domains/thingamajigs. This is why an ES always reveals multiple domains and not just ONE domain.**

It seems that today the pendulum has swung far to the right. Enterprises struggle with the proliferation of services and in some cases go through rationalization exercise to pull them back. [Should That Be A Microservice](https://twitter.com/RKela/status/1227188151887843329?s=20). Observability and performance of the distributed system becomes painful. Hisenbugs abound when you mix sync and async flows further compounded by various forms of async event driven architecture like thin events, thick events, event sourcing, CQRS etc.,

Structured domain contained in modules & layers enforced by project structure & language constructs deployed in a monolith as a self-contained system is a perfectly valid target when decomposing a monolith; however this approach is not typically adopted because enterprises have drunk the kool-aid of microservices. Regardless of the technical merit, consultants have to constantly push the boulder uphill explaining why a [modulithic](https://github.com/odrotbohm/moduliths) approach may be a better starting point than a microservices based deployment. In any consulting engagement you have to pick the right battles and sometimes this one is lost. I don't think a ONE way fits all - and we have to pick the right deployment model based on the trust, culture and engineering acumen of our developers. Note - the [app continuum](https://www.appcontinuum.io/) is also a structured modulith based approach to developing microservices. 

As a modeler I have struggled a lot with this question posed by [@aevars](https://twitter.com/andreasevers?lang=en)
> it’s not just finding the boundaries between bounded contexts that is tricky.  Is something a bounded context, an aggregate or an entity within an aggregate?

The event storming of a domains reveals the emergent structure of the domain. After ES we go through a process of convergence and reduction to categorize and affinity map events to domains. We look for key events, swim-lanes, time based milestones, language transition, semantics of words, old/new differences, surface/underwater differences to sort the universe of events into themes and cluster them into subdomains.

I think its important to revisit the definitions of some of the key DDD terms  here
- **Entities** : Something with continuity and identity. An Entity models a single object in the domain (i.e. Address, Customer), usually tied to how it is stored.
- **Aggregates** : Mark the scope within which invariants have to be maintained at every stage of the life cycle. An Aggregate is a cluster of objects that are treated as a unit. It is a graph consisting of a Root Entity and one or more other Entities. An Aggregate maintains transactional boundary for its Entities. Aggregates and Entities are not necessarily the same thing. For example, an Order Entity would represent a single Order, but would need links to the Order Items, usually tied to how it is stored. An Order Aggregate would represent the Order, Order Items, Shipping Address, etc. as a single transactional invariant.
- **Subdomains** Represents a single, logical Domain Model, and is used to break up the business model logically to understand the problem space on large systems. Subdomain is the problem space. There are three types of sub-domains - core, supporting and generic.
- **Bounded Context** : A Bounded Context is a language based semantic contextual boundary. Within the boundary each component of the software model has a specific meaning and does specific things. Bounded Context is the solution space
- **Ubiquitous language**: The consistent language spoken by all members of the team within the Bounded Context. It is necessary to rigorous, stringent, exact and tight.

This is my cheat sheet of how I think about the model after Event Storming
- System = ``{subdomains}``
- Subdomain contains ``{Aggregates, Value Objects}``
- Aggregates contains ``{graph of entities behaving as a unit}``
- `Scope (Aggregate)  < Scope(Modulith/Microservice) < ScopeOf(Subdomain)`
- Moduliths/Microservices cannot cross subdomains
- Invariants of an aggregate should be preserved in a microservice/modulith

As you can see all this becomes complicated and this is where the experience and art of the process kicks in. Experienced software engineers have seen the structure and shape of F@%&ed up and Good systems and have an intuitive grasp of the structures and shapes of the subdomains.Which is why we invented Swift because [DDD is broken](https://cloud.rohitkelapure.com/2019/10/ddd-is-broken.html).

Swift is an attempt to simplify this process of building and decomposing a system leveraging constraints to simplify the process. It is not dogmatic and you can plug'n'play other techniques in Swift. I do this all the time. For instance for a UI/UX customer facing redesign of the system, it may make sense to add an explicit notion of Actors & Systems and Value & Opportunities modeled as detractors and adders. The architecture revealed by Boris can be fully synchronous API Request/response based or a fully decoupled completely event sourced system or something that is more pragmatic and easier like an event notification based system.

The best NFL coaches adapt every game based on the opponents strength and weakness. Embrace the ambiguity  by combining different techniques EventStorming, Boris, domain story telling, thin slice definition, MVPs, story mapping, service blueprint, customer journeys, lean UX discovery to modernize the system based on first principles. This is how I think about SWIFTly modernizing a system.
