Refactoring has been practiced to some degree since the dawn of computing, but it was really Martin Fowler who turned refactoring into a software development discipline when he published Refactoring: Improving the Design of Existing Code [FBBO99], in which he defines refactoring as “the process of changing a software system in such a way that it does not alter the external behavior of the code yet improves its internal structure.” This is a book every developer should read and understand as it also contains a wealth of information on good programming practices.
Refactoring code gives developers another chance to make their software easier to work with. Sometimes when developers are deep into implementing a feature, they tend to be a bit sloppy with their naming. Sometimes developers don’t really know what something should be named while they’re in the middle of implementing a behavior. For these reasons it may become necessary to go back and review code later, looking for opportunities to improve names and make the code more maintainable.
In Agile software development, where you don’t get all the requirements up front and figure things out as you allow your designs to emerge, it’s easy to make a few wrong turns now and again. It’s still far more efficient to build software iteratively than to try to figure it all out up front. When you do take a wrong turn that limits your ability to extend a design in a certain way that may now be needed, you can refactor your code to accommodate the change without degrading the existing design.
But refactoring can also be dangerous because most code is so intertwined that changing one part can cause bugs to emerge in other areas.
Code that’s supported with tests is safer to refactor. That’s because if you make a mistake, it’ll likely cause one of your tests to fail, so you’ll know about it immediately and can fix it right away.