Many of my colleagues at Yahoo! (including myself) have very strong opinions when it comes to writing code. We all follow our styling guidelines, but then we all have opinions about how to approach a problem. For instance, if youve been following along youve probably guessed that I prefer a functional approach to solving a problem whenever possible. On the other hand, some of the colleagues steer far away from this approach and would prefer to stay out of Java 8²s stream API. However, no matter what our difference of opinions are on style, were all going for the same thing in the end: maximum readability (while maintaining required performance benchmarks). As a result, we are all true champions of refactoring code.
Refactoring is the art of rewriting code. I maintain that it is an art because you should refactor with a purpose. Whether your purpose is to optimize performance or improve readability (should be both, but these are often competing goals), youre really reworking an existing solution. Since its arguable that we spend the vast majority of our time reading and maintaining code as developers, we should be nice to those around us as well as our future selves.
In such a way, we are like authors of novels. Developers– like writers reading a best selling novel– appreciate the small details which make the code great. Likewise, code almost never starts this way. It is only after several drafts (i.e. refactorings) that code actually attains a level of maturity and clarity.
As I have already asserted, refactoring is what actually produces quality code. It is unlikely that the first time you write a new piece of code that it is going to be in its final state. As a result, constant (not to be confused with needless) refactoring keeps the minds of developers fresh on important pieces of code (these are typically the most complex and in need of most refactoring) while improving the overall quality of the product.
How do I know what to refactor and what do I do to it?
Have you ever dug into a codebase and decided to avoid a particular file and leave it as magic since it looks too complicated? That is exactly the file you want to refactor. Reading code should not be a painful process. In fact, well-written code should be very precise and probably easier to read than your native spoken language due to its lack of ambiguities (i.e. your fellow developers should never be relying on undefined behavior).
When youve identified the piece of code to refactor, you need to dig in and understand the code. In general, you should understand the context in which that piece of code is used. If its a class called PancakeMakingFactoryBuilder you probably shouldnt think about using it in the part of your code that constructs waffles. After you have established the appropriate context for which the code is intended, you should dive into the details of what its doing. Use context-clues such as method names, comments, etc. to discern both the intended and actual behavior of the code. While you gain this understanding, mark sections which feel particularly complicated or too verbose.
After having a strong grasp of what the code is doing, you should revisit the identified sections and see what you can do to make them simpler. Is there an easier way to express the logic to reduce cyclomatic complexity? Is the method doing more than one isolated operation (if so, can you break those other operations into separate methods)? Do the function names accurately describe intended behavior (caution: if this is a public-facing API method name, you should change names very sparingly)? In any case, as you answer these questions, you will find the code quickly becomes more intelligible and– in a word– beautiful.
What if my colleagues get mad when I refactor code?
If you work with fellow developers who are very attached to their code, this can be a bit of a sore subject. Of course, the first thing you should do is try to explain to them the value of refactoring. Explain it with an easy-to-understand example: a writer never submits his or her first draft for publication, so why should we? Chances are, however, you will be met with some opposition.
The bottom line is that you must refactor if you expect long-term success. Interoffice relationships are very important to maintain, but you have to perform your job to the best of your ability. Part of our jobs as software engineers is to write intelligible and quality code. I argue that the only path to this end-goal is via refactoring. Consequently, refusing to do this because it feels like grunt work or whatever other excuse people may have is simply gross negligence to perform your duties. I would try to explain this to your troublesome colleague and– even if he continues to refuse– inform him that you are only trying to improve the over all quality of your product and are not making personal attacks against his or her coding style.
If you have many troublesome colleagues that all refuse to listen, I suggest you leave. If your company doesnt have a stranglehold on a market and is suffering this type of internal strife, its not likely to go very far if you expect to win marketshare through product quality.
Refactoring is an essential part of a programmers job. If youre in school working on class assignments, this does feel like grunt work because its being done on toy projects. This initial introduction to refactoring may poison your overall view on the matter, however. As you work in the professional world refactoring is an incredibly important aspect to maintaining real and lasting products. Above all, a little bit of refactoring makes code significantly easier to read and, as a result, more robust.comments powered by Disqus