After you work long enough on software projects, it will become self-evident why complexity is your enemy. Pieces of code that are highly dependent on each other will result in a maintenance nightmare. You cannot change or upgrade anything without risking to break the different parts that are tightly connected to it.
The solution I have found that works best is “Event-Based Programming.” I did not invent it; it has been around for a long time. I discovered that adopting this pattern has made maintenance much more straightforward.
In a nutshell, your program is no longer a collection of functions that call each other in an ever-increasing web of complexity. Instead, you have components that talk to each other by raising or listening to events.
This breakdown allows you to change each event generator or event listener individually, and as long as the event format does not change, you don’t risk a break down in communication.
An event generator will say: “Hey, something interesting has happened, and here are the details.” And it does not care what happens with that announcement. It could be that nobody cares, or it could be that many will take action on that event.
An event listener, on the other hand, does not care how an event was generated. As long as something interesting happens, it will act on it.
This decoupling makes debugging super easy too! Because you can test components independently by merely looking at the kind of “chatter” they generate.
If you’re reluctant to adopt “events” in your codebase, now it’s time to make the jump.