From a certain point on it becomes very tedious, frustrating, and expensive to change code in order to implement some new requirement. For a while clean coding and refactoring help - but in the end it’s undeniable: the existing code is more of a burden, a liability, than an asset.
This is not satisfying, but it’s how things are. It’s how nature is. Every organism grows old and eventually dies. Even mountains erode to oblivion. Why should software be any different?
Adaptability in nature does not come from highly flexible, everlasting organisms, but from their finiteness. Adaption over long timespans is only possible through death of the old and birth of the new.
Existing structures can only change (themselves) so much before they break or lose their identity.
I think software development should try to learn from that. We shouldn’t strive to create immortal instances of code. Why not plan code to have a certain life expectancy? Why not see rewrites as a natural part of software development?
Sure, it does not seem to be an option to just rewrite a software which was developed over the course of 20 years. Even if a rewrite would only take a fraction of the time it would not be feasible.
But what about smaller parts?
How much time would be ok for a rewrite? If you realised a part of the software has reached the end of its life because it has become too rigid, to calcified, too cryptic to adapt to new requirements, how much time would be acceptable for a rewrite? A couple of weeks or months? Probably not years.
Let’s assume, the birth of a new generation for this part of the code was allowed to take three months.
Then how large could such a part of code be to rewrite it pretty much from scratch? Let me try a quick estimate: A developer can maybe write 200 lines of production code per day on average. A team of 4 developers then produces 800 lines per day. In a 5 day week that would be 4000, in 12 weeks it would be 48000 lines of code. Or maybe that’s a bit optimistic, so let’s say, it’s maybe just 30000 lines of production code in three months.
Please note, such a rewrite would be very different from the original process of changing the code over the course of months and years. A three month rewrite can maybe replace three years of constant updates.
For a software of 300000 lines of code in total that would mean it should be split into 10 perishable parts. Let me call them bubbles for now, because bubbles start small, then grow, and eventually burst and are gone - to be replaced by new bubbles.
Of course it’s not about a specific number of lines per bubble; come up with a number you feel comfortable with. It’s about a paradigm: evolution.
Instead of creating software as a kind of monolith with the clear fate of erosion, let’s create software as a sea of bubbles. Each bubble’s fate is to burst. But the big picture of a bubbly surface will live on - as long as requirements rain down on it.
Whether the focus of these bubbles is technical or functional, is up to you. The goal is easy rewrite. And that should be very motivating: It means a codebase does not just grow old and makes programming a chore. No, there is always some fun rewriting going on. The greenfield is always near. That sure will keep a team’s spirit high - and opens up opportunities to get new people and/or new technologies and/or fresh ideas on board.
With bubbles there are now two levels on which software exists, i.e. is born, grows, changes, and eventually dies:
- Bubbles are comparatively short lived, e.g. months to years. Once they reach old age they are rewritten in a fraction of their lifetime and then die.
- The whole of the software consisting of bubbles - maybe I should call it foam - has a long lifetime, e.g. years or even decades. Its bubbles come and go without affecting the overall identity of the software. Or should I say the foam emerges from a constant fireworks of bubbles?
Sure, in the end the whole which all bubbles constitute like a standing wave will grow old and die, too. But that point hopefully lies further in the future than with a monolith. It’s a matter of how the macro structure of all bubbles is managed.
How can this be achieved? In the end, I guess, this only works with distribution. Bubbles have to run in their own processes to allow for maximum flexibility during rewrite. A (micro) service oriented architecture will be necessary.
That said I think structuring code for rewriting can and should start earlier. First and foremost it’s a matter of mindset. And that mindset can be grown by cutting up a monolith into libraries, packets, components first. It’s a valuable exercise to modularise your code first without distribution. You’ll gain a new understanding of your code when you look at it from the perspective of rewriting. It takes time to get used to thinking in bubbles.
Image source: pixabay