No one starts out wanting to build a monolith. There are no design meetings where the architect or developers say "you know what? I think it'd be a great thing if we built something that will be hard to evolve and maintain." I think it's also fair to say that conversations like "we've got a great architecture for our system that has helped us be successful, so we need to be sure that it evolves towards a big ball of mud" rarely happen!
And yet monolithic applications do exist. Probably less than many people might want to admit, but they are there nonetheless. So the question has to arise: why? I suppose there's another related question: how? As with so many things in this life, there's no one straight answer; it's a combination of things including:
- Expediency; far too often it's just too easy for developers to hack solutions into an otherwise good architecture without spending time to understand whether that breaks the architecture. What starts as a simple, small hack can also then grow, acting as a catalyst, and a small break in the architecture then turns into a fracture.
- Lack of architect (leadership); the original architect(s) leave the project and those who come in to replace them (if they are replaced) can't control the developers or perhaps don't understand the architecture enough to ensure it remains "pure". Likewise, different developers coming into the project to either add to or replace those there already, can dilute the group knowledge and understanding of the architecture, leading to unforeseen and accidental divergence from the original plan.
- Natural evolution; any system than can be said to be architected has a point at which it's simply impossible to evolve and retain the original architecture. Take a look at any (historic) building which may have once been considered an architectural marvel and if it was left mainly alone (not extended) once complete then it's likely still something to behold and admire. But if it had extensions, new wings etc. then it's likely to be a monstrous carubuncle, unless the original architect was involved, or someone who appreciated/understood the original. Sometimes it's just easier to start from scratch and approach the problem afresh, than try to tack on new features.
- Related to the above, sometimes people try to extend software systems (services) to do more than they really should and in doing so break the architecture or create monoliths.
- Poor tools with which to visualise the software system/architecture, leading to making it harder to track changes and ensure they don't move the system towards an unmanageable monolith.
Now nothing I've mentioned so far has been specific to localised applications. It's just as applicable to distributed systems and in fact in a distributed environment the architectural issues can become even more important to understand and track. If you've arrived at a monolith then trying to fix that may involve breaking it into components/services/microservices which reside in a distributed environment, but that's not necessarily the only way, or the best way, in which to resolve the monolith problem. In fact if you don't understand the architectural issues which have resulted in the monolith then breaking it into components is more likely to result in a distributed monolith (or micromonoliths) than to fix the problem!
Yes, I mentioned the microservices word above for the first time and this is really an article about them again. As I've mentioned elsewhere, I believe in and understand the need for distributed systems composed of (micro) services. However, what worries me about some of the current emphasis around microservices is that somehow they will naturally result in a better architecture. That's simply not the case. If you don't put in to place the right processes, design reviews, architecture reviews, architects etc. to prevent or forestall a local monolith then you've no hope of achieving a good microservices architecture. And if you don't keep them in place then there's a good chance you'll evolve towards a distributed monolith.