Ever got caught up with a full fridge, picking through the items, looking for what’s in-date and what needs slinging?
Everything has a shelf life, even software. Continuous delivery of value is hard in the long term. Swift at the start, change often slows down as delivery continues.
In my last post, I walked through how development friction often increases. And how building software gets harder the more we add. Our options often become more restricted than we would want.
I asked myself: If I can understand it better, can I communicate the challenges? And if I can do that, can I create more options to manage it better?
Three Forces of Complexity
Every project is a snowflake. Reasons are complex and different for every organisation and product. However, I’ve identified three forces that we can tackle in turn, to keep our software fresher for far longer.
1. Not every bet pays out
When we begin, we know the least about what our customers need, or how we might solve it effectively. We always need to make assumptions and decisions to move. These choices are rarely perfect. Not every feature gets traction. We measure, learn, adapt.
We bet when we pick architectures and build software too; though we don’t acknowledge it as much. We gamble on what we know, or what we think might work. We take guesses at what options we need to keep and on what technologies will solve our problems.
Bad bets leave behind tech debt and feature cruft. These can cast long shadows over our future work, distorting and forcing it into shapes that aren’t ideal.
Clearly, we need to tackle the parts of our systems that are costing us, but is there more we can do?
2. Complexity grows
We build our products and systems in small slices. We create spaces and put like code together. As we go on, those places get cramped and may creak at the seams. But they still seem like good places, it's just that little bit harder each time.
With each success comes more complexity, and that complexity needs to be navigated with every new change. Even if we are prudent (and often we are not), and refactor mercilessly, the necessary complexity can become a point of development friction.
The complexity of our systems needs to be managed in more than a slice-by-slice way. We need to let our systems breathe and hold something that our engineers can navigate with low friction.
3. Need drifts
Today's news is tomorrow's chip paper. No matter how well we do at managing debt, cruft and complexity, what we build has a lifecycle. New products come to market. Our customers and our organisations develop and what they want and need changes over time.
But we need to work with what we built, to stale needs. The past curses us again.
Technologies also lose their freshness. What looks cool, well-maintained and useful can become stale and unloved. Sometimes just a major version change can cost months of work. Perhaps we should always plan for obsolescence.
How do we get out of it?
Each of these is a rising grade of system hygiene to be tackled. If we clean and manage our bets we should reduce the accidental and unnecessary complexity.
If we are aware of where our systems are hard to navigate and change and we fix and spread that complexity, we make it easier for change to happen.
If we accept that what’s needed is going to change, we can build systems that will adapt, and align with what’s happening with our product.
Success at each level should allow us to be ready to tackle the next. There is a richness to how we can solve these, which I’ll cover in the next post, suggesting tools and practices that we already know to move us forward.