Originally published on medium.
The big misconception I had about refactoring was that it's something you do only when your code is bad. And that if you have to refactor it means that you messed up when you first wrote your code and now you have to fix your mistakes.
So when I had to tell my manager that I have to spend some time refactoring, it was like I was admitting that I was not good enough to write "good code" the first time I wrote it, so now I have to fix my mistakes. Instead of spending my time adding new functionality to the project, I was "wasting" it fixing my mistakes.
That made me afraid of refactoring.
Even though refactoring is used in that case, the reasons for refactoring go much deeper than that. And most of them are positive reasons that add real value to your code. Refactoring is not all about bad code or technical debt.
You should refactor all the time when you write code. You should learn to love it, and be good at it. It will make your life much easier.
There are many reasons to refactor a piece of code. Here are some of them:
The best quote I've ever read about refactoring is:
"Make the change easy, then make the easy change" - Kent Beck
It's such a simple yet powerful statement that works on so many different levels. In terms of refactoring it works like this: Very often you need to extend or change a piece of code because of new requirements. And sometimes it looks like that change is not going to be an easy one to make.
So before you start coding the new requirements, you take a step back and think about your existing code. How can you change it (make the change easy) in a way that will make it very simple to then implement the new requirements (make the easy change).
This is where refactoring is at its most powerful. Using refactoring techniques you change the existing code, while making sure the behavior stays the same. When you are sure that there is no more refactoring to do (you made the change easy), you then proceed to 'make the easy change' and implement your new requirements.
In this case you refactored the existing code and changed the design of it, but not because it was a bad design, but because it's not longer the right design for requirements of that code. By refactoring it you improved it and added value to it.
When requirements change, so must the code design so that it can reflect those changes.
Each change of functionality is an opportunity to reevaluate the current design and see if there are changes that can be made to improve it.
So after you make the functionality changes that come from the new requirements, it's time to refactor. Maybe a method should now be extracted to a new class. Or the design pattern that was used here, no longer looks like the right solution.
But don't worry about anticipating future requirement changes when designing the solution for the current requirements. You don't have to. Make sure your current design is the best for the current requirements. The confidence you get from your refactoring skills should keep you from being afraid of any future requirement changes. If they happen, you know what to do.
'What' the code does and 'how' the code does it can often be looked at like two different problems that can be worked on separately. The 'what' being the functionality of the code, and the 'how' being the design of the code.
It's often very helpful that you first focus all your efforts on getting the functionality right. You don't care about the design at first, because you are confident your refactoring skills will help you get the best design afterwords. When the "what your code does" (functionality) is already taken care of, you are free to think about the how (design).
Refactoring relieves the anxiety of having to get everything right the first time round. You don't have to worry or spend too much time trying to find the perfect design for your solution right away.
You can make it good enough for the time being, work with it for a little while so you can get a good feel for it, and then came back and refactor it later.
Every solution can be made better when there is feedback for it. And for you the feedback in this case is your own experience while working with the code. You refactor and make it a little bit better every time you have to work with it.
That does not mean you failed the first time round. You just have more information to make it a little bit better now.
You are working on someone else code and you notice that a part of it can be made more understandable if you do some refactoring on it. If you rename a method or if you extract a piece of code into a new method it will make it more readable and understandable for anyone working on it in the future. So you refactor it to improve its readability, and with that increase its overall value. You should always try to leave it better than you found it.
Refactoring is not all about bad code - it goes much deeper than that. There are many positive reasons to refactor also. Recognizing the reasons for refactoring along with refactoring techniques is something that you should master and do every day if you want to become a better developer.
A useful book to help you improve your refactoring skills is Refactoring By Martin Fowler.