Before I get started, the following post is my understanding and how I want to use refactoring, taken from the first 3 chapters of the book "Refactoring" by Martin Fowler.
I want to note the tech choices that I use in my day to day job. These might not be necessary to understand the post but might shed light on places where my example does not make sense.
Say I get a call to add a feature. This feature intersects with the existing code, so I get on modifying the code to add this new feature.
Say I in my codebase have a number input, and my new feature request is being able to control whether or not the user can input decimals.
My first instinct is to add the function to control it, then wire up the change method to use the new function, and from there add a prop to the components called, let's say
withDecimal, and fix the places I need to fix.
During all this, I make sure not to break any existing uses of my number input component.
While there is no apparent fault in this, there might be a long term problem, if this is the end of implementing the feature.
I have done all the things now, and the new feature is working. Yay.
But at what cost?
Might be free, might not. Just stopping after the feature is implemented, you will never know, or you will learn it the hard way, 2 months down the line, when the number input component is 400 lines long.
From here on out, I want to make sure the features I implement is tested, and then take a good gander at the new feature I just implemented.
In doing this, I will try and see if what I did just solved the issue, and if the solution I made is as clear and pristine as it can be. If not, I refactor the code to be clear, concise, and understandable.
And also, while I'm here, I check if anything else needs tidying up and if it's a small change, I make it.
In the book, this is called the "campsite rule": always try to leave the code a better place than it was in before.
But what to refactor? Good question.
Instead of me telling you how a true master refactoring, our great benefactor has made the first chapter of his book free for all to read. Download it from here.
The only thing I'm doing differently is that after I have implemented a feature, or changed some existing code in my codebase, I make it an exercise to go through the component again to see if I can make it clearer.
A set of rules I used, as learned from the book:
- Is there any comments, if so, can I refactor the code to make the comments unnecessary?
- If I have long functions, can I refactor parts of them out into separate functions with good names to increase understanding of the "long" functions flow?
- Do my filenames match the content of them? Or do it export a NumberInput component from a TextInput file?
- Can I extract logic to util files, and reference them from my view files to decrease clutter?