Nobody sets out to make an unmaintainable mess.
Probably the most common complaint from software engineers is that they never have the time to eliminate technical debt. Productivity and velocity go down, bug rates go up, product performance plummets, and customer complaints skyrocket. Technical debt is always related to complexity, and hidden complexity is still complexity.
Years ago, my wife overheard a conversation at her hair salon, between another client and a her stylist. It was funny because they were both talking about the cost of a purchase, but they didn’t understand each other. One of them thought that the cost was the same as the price. The other thought it didn’t cost anything if their minimum monthly credit card payment didn’t go up.
A “buy now, pay later” attitude is typical of the short-term planning in software development, but it’s often secretly “buy now, pay never.” People may expect to move on and leave the problem to someone else.
More often though, people just don’t think about the long term cost of adding anything, but just focus on what it will take to add it right now.
The Difference Between Simplicity and Easiness
One of my favorite tech talks of all time is the “Simple Made Easy” talk by Rich Hickey.
Some of Hickey’s main points are:
Simplicity vs. Easiness:
- Simplicity: A lack of interleaving or entanglement; something that is easy to reason about and understand.
- Easiness: How close or convenient something is in the short term, often at the expense of long-term simplicity.
Simple ≠ Easy:
- Simple solutions often require more upfront effort and thought.
- Easy solutions can lead to complexity over time because they prioritize speed and convenience.
Complexity is the Enemy:
- Complexity makes software harder to understand, debug, and maintain.
- It often creeps in through unnecessary dependencies, overly clever abstractions, and entangled components.
Choosing Simplicity:
- Simplicity requires deliberate decision-making and a willingness to forego immediate gratification for long-term benefits.
- Be critical of frameworks, tools, and patterns that trade clarity for convenience.
Avoiding Creeping Complexity
Unfortunately, avoiding creeping complexity is not as simple as slamming your wizard staff down on a bridge and shouting “You Shall Not Pass!” Complexity is not a giant flaming Balrog, it’s more like a litter of adorable little baby balrogs with bright black eyes and little twitchy noses.
The product manager wants to add just one more Javascript tracker to the 12 that are already deployed on your web site. A developer wants to add a different framework for dependency injection, since that’s what all the cool kids are using these days. A designer wants to add a new icon library for a Gen-Z theme. An architect wants to add a new more scalable database, for when you get a billion users (even though you only have a thousand today).
Removing things is much harder than adding them. If it’s “just” internal you will rarely have permission to remove it since adding a feature or fixing a bug will always be higher priority. Removing a feature that users have seen is so hard it might as well be impossible - someone will have built an entire application around that feature, even if it’s really a bug.
The trick is to avoid adding complexity in the first place.
Complexity Is Like Junk: Hidden or Not, It Costs You
- Cognitive load: Developers must remember, learn, and adapt to what’s added.
- Maintenance: Every addition needs updating, fixing, and integrating.
- Support: Increased complexity often leads to harder debugging and user issues.
- Security: More code equals more vulnerabilities.
Summing Up
Eternal vigilance is the cost of simplicity.
The cost of complexity is like a monthly subscription, or rent. There’s no way to pay for it up front.
And the answer, to “will it raise my monthly payment”?
Yes. Yes it will.
Use the share icon here if you liked it.
Thanks!