This post appears as part of a series of Cloud Native Transformation Patterns, which begins with Cloud Native Transformation Patterns: Introduction. These are condensed versions of the full patterns appearing the forthcoming book, Cloud Native Patterns: Architecture, Design and Culture, a joint project of Container Solutions and O'Reilly. Complete and in-depth information regarding each pattern, including case studies from real-world Cloud Native enterprise migrations, will be found in the book publishing in Spring 2019!
In software design, Modular Architecture refers to separating the different functions within an application into independent yet interrelated pieces. Java engineer/architect Kirk Knoernschild defines a software module as a deployable, manageable, natively reusable, composable, stateless unit of software that provides a concise interface to consumers. Yes, pretty much the opposite of a monolith!
The sheer size and complexity of monolithic applications limit our human capability to understand them. Dividing them into smaller and more manageable pieces makes them easier to understand, easier to implement, and faster to iterate.
Modularity is not exactly a new concept. It is, however, particularly well suited to Cloud Native, where we typically implement it in the form of microservices architecture. In this form, modular architecture has already revolutionized the way modern software applications are developed.
The Modular Architecture pattern applies when your company is moving to Cloud Native with the aim of delivering software faster to their clients.
Your engineering staff size ranges anywhere between a dozen for a small to medium business, up to a few thousand people for a large enterprise.
Naturally, as your business has grown, the complexity and scale of your software has grown along with it.
In the first stage of the Modular Architecture pattern, companies are often still firmly based in a monolithic plan release schedule/approach. A few of the problems that this pattern applies to include:
Inevitably, the solution supported by the Modular Architecture pattern is to kill the monolith: split applications into smaller modules where each individual component can be built, tested, deployed and run independently from all the other components.
This works by limiting the complexity of each component while enriching their connections. First, break down the application’s functions to the most granular level that is possible and that makes sense, given the organisation’s needs. After that, create connections to join the components in a wider network of higher complexity. (So: complexity of components themselves is bad, but network complexity is ok and even to be expected). These connections must be well defined, with well established messaging/communication established between them, and implemented as APIs.
Each module (microservice) is assigned as the full responsibility of a single small team. This ensures that the complexity of each module will not go beyond a manageable limit, and that teams stay nimble. Able to quickly adjust their piece of the application to changing needs as they arise, and also responsively coordinate their piece with other teams.
New systems are created from a large number of small components with a complex web of connections reliably communicating with each other via APIs. Small, independent teams work on separate modules and deliver them when needed, as needed, with only limited coordination required across other teams within the organisation.
Cross-functional Teams, Continuous Integration, Continuous Delivery, Common Services, Libraries & Tools, Communication Through APIs, Dynamic Scheduling, Automated Infrastructure
Want to learn more about Cloud Native? Download our free eBook below: