by Bryan Johnson Jul 05, 2017
There is no amount of upfront planning that prepares you to write the perfect code the first time
Refactoring is perfecting code. When it comes to building and maintaining software one of the most common questions we are faced with is “When is a refactor necessary?” This is a question that can be difficult for developers and project managers to answer. But why is refactoring necessary in the first place?
There is no amount of upfront planning that prepares you to write the perfect code the first time, and even if there was, contrary to popular belief (mostly among programmers), we are not superhuman—we make mistakes. Often times while writing code, you start to notice things wrong with the way it works on the lower level, such as performance and usability, that were missed in the higher level planning.
If there is a problem left in the code too long, it will start to grow exponentially. Before long, developers will be spending more time fixing bugs than developing new features. No one likes to focus only on fixing bugs.
Now, refactoring code doesn’t have to be a big process, and it doesn’t have to be just on old code. A great strategy for refactoring code within a test-driven development paradigm is James Shore’s method—referred to as “Red, Green, Refactor.” The idea behind this strategy is that nobody writes perfect code, so when you are writing code for a feature you should go back to refactor it a bit before you move on to starting the next feature.
While you are adding new features, you are bound to see some code that has existed for quite some time. This is your chance to make sure that variable names make sense, it is not too complex, and there are no problems with it. This will prevent future bugs and problems, along with keeping the code maintainable. It is a good idea to add comments in as well.
There are a few different kinds of refactors. They can be split into three categories: small refactors, major refactors, and starting over.
Small refactors are significant enough to be separated into their own task, but you should be able to get it done in a day or less. These should involve fixing sections of code that are becoming unmaintainable. This may consist of code that is getting too complex or a method that is very long. Splitting up logic and large methods into several small ones can help in this case.
A small refactor may also be needed if you have large files. We have all had some files we were writing code in that reach 500+ lines. These should be broken down into smaller files. Large files can easily become unmaintainable because that code could be doing a wide variety of things. It is better to have more files with less code in them—this gives you the ability to better organize your code.
Major refactors are when you have large sections of code that need to be fixed or changed. A major refactor could be necessary in a few instances: when it is unmaintainable or needs an adjustment in code structure due to change in the behavior or structure of a feature. Another common cause for a major refactor is updating packages employed in your code or changing the framework used in the software.
Starting over on a project is sometimes the most viable option. There are two common cases where scrapping the project and starting fresh makes sense:
1) changing the language/framework you are using
2) when there is more time spent working on bugs than working on new features.
When starting over, it would be wise to go through the existing project and document everything it does, then build your specifications according to your documentation.
Refactoring can be quite a chore sometimes, but it is worth it. While we set out to write perfectly organized, documented code with no bugs in it in the first place, sometimes it doesn’t happen. Refactoring is your opportunity for redemption. If you follow the practices of test-driven development and “Red, Green, Refactor”, it will greatly reduce the need for major refactors.