Refactoring is a term you’ll hear thrown around a lot in software engineering discussions. If you’re unfamiliar with the term, you might assume based solely on the content of those discussions that it’s a mystical advanced programming technique known only to experienced developers.
But what exactly is refactoring?
Sorry to burst your bubble, but refactoring doesn’t do anything to programs.
It doesn’t improve the program’s performance. That’s “optimization”.
It doesn’t fix problems with the program’s logic. That’s “bug fixing”.
So why all this talk about refactoring?
Simple, it’s all about improving the code–the part of the program where developers spend a great deal of time on.
To give you a glimpse of the importance of high quality code, here’s an excerpt from the preface of the (or the) Java book Effective Java:
Programs, unlike spoken sentences and unlike most books and magazines, are likely to be changed over time. It’s typically not enough to produce code that operates effectively and is readily understood by other persons; one must also organize the code so that it is easy to modify. There may be ten ways to write code for some task T. Of those ten ways, seven will be awkward, inefficient, or puzzling. Of the other three, which is most likely to be similar to the code needed for the task T‘ in the next year’s software release?
The perceived lack of value that comes from refactoring usually turns off managers. Why let developers spend time “beautifying” their code when they could spend that time writing new programs?
In the long run, however, “beautiful” code reduces overall effort because of the inevitable changes that will come to those programs.
A basic example would be refactoring redundancy. If a certain piece of code is copy pasted all over the system and it’s processing logic is suddenly changed somewhere down the line, an unfortunate developer would have to comb through the system looking for instances of that code. Extra effort would also be spent later in case that developer missed a couple of instances of that code.
Had the offending code been refactored out earlier, all that effort could be reduced to just a couple of seconds.
Of course, you shouldn’t ignore context here. If the project is already nearing its deadline and there are still a lot of programs pending coding or bug fixing, refactoring is going to be a bad idea. Not only will it further delay the project with its extra effort, a botched refactoring can introduce even more bugs to the system.
There are many ways to go about refactoring code, and indeed, many books (like the seminal book on refactoring by Martin Fowler) and articles have been written on the topic. However, beginners can use a few things to get started on refactoring.
First is to keep in mind the quote I mentioned a while back:
Copy and paste is a design error.
Redundancy is one of the easiest programming defects to detect: whenever you get to copy-paste more than a handful of lines of code, it’s time to refactor. Fortunately, the refactoring process for this is quite easy. You can extract the offending code to another function, possibly to another class so that other classes may use that function.
Another basic approach is to review Object Oriented Programming and its principles. Refactoring is about reducing complexity and improving maintainability. In other words, when you’re programming in an OO language, it’s basically just doing the right thing. Not only does this mean that you should try to reduce redundancies in your code, you should also apply the other OO concepts like loosening the coupling and increasing the cohesion of your classes.
You might ask, “Why not just do things right the first time instead of going back and refactoring your code?”
Well.. it’s not that easy as it sounds.
First off, unless you’ve done countless refactorings before, keeping refactoring in mind while coding tends to slow down a developer. It’s like a writer who focuses on the technical details (grammar, structure) of his writing instead of letting his ideas flow out and just leaving the merciless editing for later. Because of this, it’s generally a bad idea to think about refactoring while coding.
Even if you think about refactoring while coding, there are some refactorings that can only be seen once you finish an entire module or when you integrate the program into the system. It may be as simple as the “code scattered throughout different classes” as mentioned above, or it could be as drastic as rearranging a class hierarchy.
Finally, there’s the creator bias. There’s a chance that a programmer might not see possible refactorable parts of their programs just as they might not see the bugs in their programs. Code reviews, pair programming, automatic static code reviews and the like can point out these problems to the original developer.
And that’s it for the basics of refactoring. Next we’ll try to cover the next step after OOP and Refactoring: Design Patterns.