Code is never perfect the first time over, specifications change and there is always pressure when developing a new feature. Thus the programmer has invented the word refactoring. This word implies that when a programmer stumble upon the code the next time or there is time to optimize the programmer will use that occasion to refactor the code into a better state. On small things this might take a minute on bigger things a refactoring can take up to several hours. But there is always that point when a developer thinks about if it is really worth refactoring it or if it deserves a rewrite.
The rewrite is a more radical approach. You take a piece of working software and trow it away to be completely rewritten. Better optimized, better functionality and build from the ground up to be a better performing piece of software than the last iteration. David Heinemeier Hansson once lovingly said about 37signals Basecamp; “Sometimes it is time to take out the old trash and start over”. And that is what 37 signals did. They rewrote Basecamp from the ground up and they got a better product.
So when does the grey need to turn into one or the other?
Refactoring is there for a reason. Making the code more efficient, more readable and more maintainable. We find ourselves doing this constantly and refactoring is often part of a practice that is called boyscouting. Boyscouting is the rule the boy scouts have they go when camping: “Always leave your camping place behind you cleaner than you find it”. This allows developers to improve code surrounding the thing they are working on and leave a cleaner codebase behind them than they found it at.
Do not spend more time time than you are comfortable with.
Boyscouting and refactoring is all good, but sometimes spending time on refactoring can become more than the actual work on the thing you were working on. This should be a clear sign that the code is in need of a rewrite. If the code is bad enough that you will lose productivity over it the next time somebody touches that part of the code it will be the same all over again. If that is the case, kill it and rewrite it. This will save you time in the future and can improve performance, functionality and code quality in all measurable factors.
But it is not always. The code might be okay and not bad but there might be a lot of room for improvement. But in general the code might be slagging a bit behind what it should be. This is actually not a sign to do a rewrite but to have a boosting session with the team who created the code. The slag created came from somewhere and can therefore best be treated at the root of the problem.
How is code slag created?
Slag comes mostly from either inexperience, time pressure or something personal.
An inexperienced developer might not write the best code but that should not be a problem. Learning is part of the process and should come natural to a developer. Inexperienced developers can be assisted by getting more senior developers to look at their code in code reviews. Another option is to have them do pair programming sessions with more senior members of the team. An inexperienced developer should never need to feel alone in a team.
Time pressure is always the developer’s worst enemy. When pressure is high mistakes will be made and problems will be caused. There is of course a balance between pressure and slack where healthy pressure is actually a lot better than no pressure at all. A healthy pressure allows for refactoring, rewriting and education but tries to keep the train moving forward as much as possible. The best solution is to always work in this healthy pressure state. This however is not always the case, sometimes things need to be done fast and furious. What you need to keep in mind is that after the crisis is averted you need the original time you estimated to do the task again, properly.
The personal problem is the most vague and hardest to counter. Even developers are human in the end and no-one can perform at their best when their down. The only thing you can do as a manager or director is to make sure that the developer does not have to care about thing he does not need to care about. This may involve making sure they have coffee or to pay them enough so they can pay their rent. But in the end a developer cannot function as they should when not in a content mental state, it just reflects on their code. If this case happens, make sure they can do other things or have the developers do pair programming. The reduces the slag dramatically but just giving them somebody to work with.
Just like anything related to software development, the ultimate sources are the developers. They create and maintain the code and are ultimately responsible for it. I think that code is never owned by just one developer. It is owned by the whole team that is working on that codebase. This is why when there is slag at a certain point in the code the team is responsible. Working together as a team to create better code together is one of the most important functions a team has. Help one another to get better and to improve the performance of the team. Ultimately the team is the owner and responsible for the team. Let them work it out and assist where you can.
From refactor to rewrite
The transaction from refactoring to rewriting can be really natural but can also be very abrupt. The two types are always almost related to the amount of work it would take to do the rewrite. When the rewrite will only take a relatively short period to do the rewrite can have a small talk about it within a team and then just to it. No fuss, not a lot of change in functionality simple and clean. However sometimes a simple rewrite might not be enough, a major area of the code has been a problem. These things have to be discussed in order to be able to do it properly.
In a rewrite you would expect the same functionality to be rebuild. I do not completely agree with that, completely rewriting the code without also considering changing the feature is in my eyes a waste of time. As you are rewriting you have the perfect opportunity to reconsider the decisions that have been made about the functionality last time. It also has an economic value to combine a technical and a functional rewrite. Two birds with one stone. If you are working on the new functionality you will need to keep an eye out for time. Do not overspend and over complicate the rewrite in order to just add some functionality. You can do that later on when introducing a new feature. Keep it to changing existing functionality.
Now the actual big question, when do you actually let a refactoring become a rewrite?
There are several reasons why you could consider going for a rewrite. The first is that the system is has some many parts that need a refactoring that it might be a better idea to actually start rewriting it. This mostly stems from code slack or a lot of changes being done over time. This is also one of the second reasons for a rewrite, age. Sometimes you need to work on software that has been around for more than a decade. In general due to updates in techniques and changes in maintained versions of libraries and systems you are building upon a rewrite might not be a bad idea. I’ve encountered a system that was 15 years old and was relatively poorly maintained over the years. A rewrite was desperately needed. Another reason is maintainability. Sometimes a system is no longer maintainable due to operating cost or the limit of the way things are done. If it become harder to sustain the system you might want to take a look at doing a rewrite.
Dangers of a rewrite
Interestingly enough a rewrite is not without danger. There are many ways you can run aground when you do a rewrite. The most common problem has to do with not thinking it through enough as it might be a bigger task than you think. Not properly laying out what the system was doing and making sure you plan every single item let’s you underestimate the work that needs to be done. This can lead to frustrating delays or even worst unwanted lost functionality. Make sure before hand you map out what needs to be done, how long it’s going to take and prepare for any planned loss in functionality.
Another danger of a rewrite is that you can get lost. Lost because a rewrite implies that the system will have to not develop forward while your doing the rewrite. Users will use the old system while you are writing your rewrite. This makes for no forward movement and you might get some users complaining. But that is not your biggest worry. As your users are using the old system you are building something new and making improvements. With the pressure of the users you can be tempted to start building new functionality. Letting the users your building things for wait even longer and even more crucially let your new system be untested in the field for longer then is required. Make sure you finish before thinking of doing new things. I know the temptation is there but just don’t. It will only have your users wait longer and let your system be unused before you implement new things. A rewrite should have a defined beginning and end with per-defined features.
I got myself into a really required rewrite. The system that was created did not scale at all. So, what do you do? We rewrote it. Problem was we did not estimate all the different features, we just started building. Half way we had to change functionality as users were desperately asking for it. The users were waiting for some time and had us rush a release resulting in massive failure, simple because we did not know if it would work. In the end we even got caught in some technical issues. The total rewrite took almost 11 months and almost cost the life of the company.
That is a story on how a rewrite can go horribly wrong!
It doesn’t always go that wrong. I’ve actually had more normal cases and even some really good rewrites. But you must always be on the lookout for that problem. It’s not about you being a bad coder or about not keeping to the principles enough. A rewrite is as much of a technical as a business decision. Both need to be invested a 100% to the time put in. Make sure planning and understanding of the problem are number one priority with both business and technical staff.