Continuous refactoring vs software rewrite
“This code base is a mess. How did we get here?” “This user interface has no consistency. It feels like every feature is its own app.”
These are common cases of code rot, or application rot. The developers delivered the initial version and never looked back. It’s a hard thing to combat, because you have to iterate at the same pace as new features are being added, otherwise it’s a slow rot that creeps in without you immediately noticing.
small incremental software iterations
Most iterations are not work you plan and estimate as a thing of itself. Sometimes you do when it’s a major refactor with obvious business benefits, but not always is the benefit as immediate.
Continuous small code refactoring or other tweaks/improvements to the software product are the best strategy to combat code rot and maintain the quality of the software product. Their immediate impact is relatively low, but their long-term impact is the difference between a good and a bad software product. You want these small but continuous increments because they are easier to integrate and get feedback on. They also ensure that minor problems don’t become colossal problems over time, causing interrupts to develop new features.
But how do I get the time to do all these iterations you talk about?
When the feature backlog is breathing down your neck, it might seem challenging to perform the required iterations to maintain and improve quality.
The good news is that small iterations are not something that is planned in a software project. But how is this good news? It means that it is your responsibility as a software developer to apply these refactoring cycles continuously while implementing new features. This also means that when you estimate work for a feature, you consider some time for necessary refactors. It’s not something you express explicitly during estimation sessions, it’s just part of the work required to implement the feature. So this process is completely under your control. Of course, be sensitive about the time you spent on these refactors, because this process can be almost endless. So try to find a good balance between delivering new features and improving quality.
large software iterations
Larger iterations, such as a major upgrade of the framework you’re using or overhauling the UI, are things that should get planned in the software project. These are iterations that typically take more than a day (or even weeks, months) to implement. Given reasonable product management and customers, it should be easy to plan these improvements, because they provide obvious benefit in terms of security, performance, user experience, stability, …
When to start from scratch and do a full software rewrite
“This legacy user interface is an usability hell and only works on Windows. This is costing us money.” “This legacy component doesn’t integrate well with our current stack, it’s a constant struggle.” “We are writing everything ourselves, while this other software ecosystem has all these libraries available.” “We’ve really underestimated the issues with this approach. Let’s revise now before we sink in more time.”
While you certainly don’t want a full rewrite of your software product every year, there’s a time when the current version of your software system has reached its end-of-life. While it’s still an important part of your organization, it’s costing more and more to maintain it and add new features. Users of the software are also feeling the negative impact on their day-to-day work. This means it’s probably time for a full rewrite and a new technology stack use this fresh start optimally.
There might also be a time where your team has started a new project on a certain software stack, but it isn’t working out as expected. Instead of spending even more time into this stack, it might be better to start from scratch and apply what you’ve learned from the first try. This can sometimes mean throwing out months of work, but it is to the benefit of the product, team and customers. Therefore, in projects with a tight budget or delivery date, it’s important to shift quickly.
Tip: bad code quality should almost never be a reason to perform a full rewrite. If the team’s code quality practices lead to this situation, then a full rewrite will almost certainly lead to the same situation again. Instead, align the team around some common code quality practices. Then try to combine small and large iterations on the code base to improve the quality gradually. Meanwhile, you can keep releasing new versions and improvements to end-users.
And finally, there’s the R&D environment, where multiple full iterations of a software component are quite normal. Starting with a proof-of-concept, in a software stack were it’s easy to show the idea quickly (iteration 1).
From there, the team either uses the same software stack to build out the complete component, or uses a completely new software stack, which is aimed for production use (iteration 2).
After this first full iteration, the team will notice several shortcomings (e.g. performance, flexibility, …) and they try to solve these in the current stack, but notice that they are reaching the limit of the stack.
Finally, they decide to do a full rewrite (iteration 3) in a new stack based on the knowledge they’ve gained through iteration 2.
This is a normal process if you’re developing something that is completely new to the team and is trying to push the limits.
Note that actually none of these rewrites actually start “from scratch”. They all build on the previous iteration by taking along lessons learned and applying them to the new iteration.
Iterations are a critical part of delivering successful medium to large software projects, but provide even more benefit after delivering the first version for long-running projects. This is when you’ll be able to gather valuable feedback (from users, metrics, …) while the software is being used in production. Feedback to iterate and make the software even better, while applying your own iterations as well on code that begs to be improved.
The biggest enemy of these iterations are projects with a fixed scope, budget, delivery date and without the option of a follow-up budget. But those kinds of projects warrant a complete article (or book even) of itself.