During and throughout the development process, code can go wrong. Unfortunately, code can develop glitches or simply not function in the way the developer needs it to function. There are different methods available to software developers to work around and solve these coding issues. One popular method is refactoring. Refactoring seeks to improve code at its simplest, smallest iteration.
This article is specifically aimed at those developers who have are struggling with their code and have no idea where to start with refactoring. Additionally, developers who have limited experience with refactoring and need some guidance on how better to proceed with this aspect of programming will benefit from an exploration of this topic.
Martin Fowler is one of the leading refactoring gurus. He authored a seminal book, along with Kent Black, that was first published in 1999 and titled Refactoring. Additionally, he launched an indispensable website: refactoring.com. Fowler defines refactoring as, “A change made to the internal structure of software to make it easier to understand and cheaper to modify without changing its observable behavior.”
Sydney Stone, a leading software development writer, sees refactoring as a software development approach used in DevOps that “involves editing and cleaning up previously written software code without changing the function of the code at all.” Conversely, refactoring does not mean rewriting code or “fixing” bugs.
Refactoring has some key aspects worth knowing:
- Crucially, it alters the internal structure of code without changing its external behavior
- Each iteration or refactoring should be a tiny transformation
- A single refactoring does very little by itself but can affect a significant change to the code’s behavior as a sequence of iterations or refactorings
- It helps developers better understand code that may not be working and eases any future work with the code
- It should not be a “special event” but a normal, built-in part of programming
- It is a disciplined technique, not an ad-hoc “nice-to-have”
Refactoring Is Simplicity Personified
There’s a very simple reason why each refactoring should be as small as possible. By doing so, you ensure that no single refactoring can seriously disrupt or harm any coding system during restructuring. A small refactoring is also less likely to go wrong. Furthermore, it keeps the process less complicated.
Taking the small steps inherent in refactoring can enable frequent testing. This should help a developer detect mistakes in code in a more timely manner. This ‘keeping it simple’ aspect of refactoring can help to resolve the ‘technical debt’ that exists due to flawed or dirty code.
There are even ways in which refactoring can be objectively shown to improve the over-complexity of code, with one example being the use of cyclomatic complexity.This approach measures the complexity of a program, including a program’s over-reliance on branches, loops, or switch/cases. Refactoring can help identify those factors that may require redesign.
Refactoring Helps Improve Code
Essentially, refactoring builds on that which already is, for example, existing code, and more specifically, its improvement. After all, the full title of Martin Fowler’s book is Refactoring: Improving the Design of Existing Code. But Fowler doesn’t see it as a means of cleaning up code. Rather, it’s one specific technique a developer can use to improve the health of the existing code-base.
Fowler prefers to use the word “restructuring,” which is a deft means of reorganizing code to make it more efficient and by extension, better. Ultimately, intelligent refactoring should make code more efficient and maintainable. You can see how Java code can be cleaned up and improved using refactoring in this example using part of the Test Task class:
Another example in Java shows how factoring can help to improve extracting a variable:
Further Refactoring Benefits
Refactoring is not only about helping improve or clean code. Its other benefits can include:
- Reducing technical cost to help prevent more costly errors from arising later
- Improving a code’s readability, especially important for other or future developers who may work on the code
- Making the quality assurance (QA) and debugging process run more smoothly and efficiently
- Aid in preventing bugs from arising.
- It favors reusable design elements, including design patterns and code modules
- It favors low coupling, whereby different modules are highly independent from each other
- Helps adherence to the single-responsibility principle (SRP), ensuring a class in a software program has sole responsibility over a single part of the program’s functionality
Further Refactoring Considerations
Refactoring is tailor-made for Agile software development: it encompasses doing each improvement one step at a time, followed by testing – in essence, an Agile approach. No wonder so many developers who use Agile methodology are huge fans of code refactoring. One Agile expert goes as far as to proclaim: “Refactor Or Die”.
When considering refactoring, it is worth noting Martin Fowler’s four principal reasons to refractor:
- It improves the design of software
- It makes software easier to comprehend
- It helps detect bugs
- It aids in executing the program faster
When To Do Refactoring?
When to undertake refactoring can be intimidating for the unseasoned or unknowing developer. Key reasons or times to do refactoring could include:
- Prior to key changes. Refactoring can be an invaluable exercise before adding any updates or new features to existing code
- To improve attributes of code. These can include objective attributes such as length, duplication, or coupling and cohesion of code
- To prevent code rot. Duplicate code, myriad patches, bad classifications and other programming flaws can seriously hinder code, which refactoring can address before they arise or get worse.
- To improve post-launch code. Refactoring code already released to market may sound bizarre, but can be beneficial to the given software and help detect or remedy flaws before the market does.
When Not To Do Refactoring
Refactoring is not a ‘cure-all’ during development. There are instances when refactoring is not fit for purpose and worth remembering:
- It should never be used if it could affect the performance of an application
- There are times when issues with code are so far gone that it would be better and more efficient to simply re-do it all from scratch
- Refactoring can be very time-consuming and become a convoluted process, often referred to as a ‘a rabbit hole’) and is thus best avoided when development time is tight or deadlines are looming
- If the software is working, leave it alone because refactoring could cause undue time delays and issues
The good thing about clean code is that it means design elements and code modules can be reused as the basis for code elsewhere. Refactoring, though not a solution for dirty code, can help achieve and maintain clean code.
Code should be as efficient to modify as possible, both in terms of time and cost. It should also be easy to understand. As Martin Fowler states, “Any fool can write code that a computer can understand. Good programmers write code that humans can understand.”