Let’s talk about the principles of refactoring!
In this series, I share my top takeaways from the book Refactoring by Kent Beck and Martin Fowler. I definitely recommend reading the book to anyone interested in learning more about refactoring.
In Part 1 of this series we took a glance at refactoring in a more general sense. In Part 2, we will look at when and why to do refactoring and some more guidance on how to do refactoring.
Chapter 2 - Principles in Refactoring
In Chapter 2, Martin Fowler shares the definition of refactoring as:
“A change made to the internal structure of software to make it easier to understand and cheaper to modify without breaking its observable behavior”.
The term “observable behavior” refers to the public interface of the software. An example to that would be the public methods of a class that other classes call to interact with it. The definition makes the purpose of refactoring clear again. It is to make software easier to understand and restructure in a way that making a change is easier.
Which takes us to our first takeaway.
1. Refactoring should be Economic
I love cleaning/restructuring a piece of code! The proud feeling I get looking back at the changes is inexplicable. That’s why this was a good realization for me that we refactor for economic reasons. We should refactor not only for the beauty of the outcome but for the economic benefits we get in the long-term.
Martin Fowler mentions, we are professionals and responsible for getting the job done. And refactoring is an amazing tool that helps us achieve this goal as efficient as possible.
2. Refactoring is a Judgement Call
If we were to list those:
- Improving the design of the software,
- Making software easier to understand,
- Finding bugs in the software,
- Increasing the development speed…
Last one in the above list may sound contradictory to some people. Because they consider refactoring as “more work”. This might only be true for some cases where the actual change is so small. But it is important to remember that refactoring pays dividends in the long-term.
So it is usually a judgement call we need to make “to refactor or not to refactor”. The ability to make the right calls will develop over time as we face more of them in our career. As a starting point for making these decisions the book mentions the “The Rule of Three” by Don Roberts:
“The first time you do something, you just do it. The second time you do something similar, you wince at the duplication, but you do the duplicate thing anyway. The third time you do something similar, you refactor”.
3. Identify Opportunities to Refactor
How do we find the correct time to refactor? We need to learn to identify those certain occasions that suits well for refactoring.
- When adding a new feature or fixing a bug. Why? It is easier to do any modification on a well-structured code base.
- When trying to understand a piece of code. Why? Renaming for the better, untangling the dependencies gives us a clear picture.
- When we came across a piece of code that could do what is doing better. Why? Well, because “Always leave the campground cleaner than you found it.”.
- When doing code reviews. Why? It is a good opportunity to share some perspective with your colleagues. This may not be suitable for the pull-request type of code review since that process takes longer. It is more appropriate when doing pair-programming and you can discuss the suggestions.
- Having a planned refactoring time. Why? In some cases - usually for the ones involving a legacy code base - refactoring may not be an easy thing to do. For such cases, planning ahead of time to pay the debt of the previous development decisions is a good call.
4. The Two Hats Metaphor / Wear Only One Hat At All Times
The book mentions a good metaphor “The Two Hats” (by Kent Beck) for the way Martin Fowler does refactoring.
It represents dividing the development time when using refactoring into two. One hat for adding a new functionality and the other for refactoring.
When we put on the first hat, we should focus on adding the new functionality (and its tests, please) only. We should not be making any changes to the existing code.
When we put on the second hat, we should focus on restructuring the existing code and keeping the tests pass. We should not add any new functionality (not even new tests).
We may keep switching the hats during the development process. But remembering which hat is currently on is essential.
Kent Beck shares this note about The Two Hats:
“Once the refactoring hat is on, note the things you think are not right about the code, but resist the temptation to change it right now, the code should be doing exactly the same thing after you’re done refactoring. Then, you can switch your hat and go back to fixing the implementation.”
The book mentions great ideas for dealing with the common problems of refactoring. These problems include:
- How do we not let it slow down development,
- How should we arrange our code ownership for a suitable environment for refactoring,
- How do we deal with legacy code base,
- How to make use of branches in the version control systems,
- How to deal with database involving refactorings.
I will not go into the details of these ideas. It is better to use them as a reference and refer to those sections when we face those problems.
Thank you for reading, that’s all for Part 2! I hope you find these points as useful as I do. And, stay tuned for Part 3!