posted under category: Software Quality on April 12, 2011 by Nathan
We left the easy list of things to do that will help you pay down your technical debt, but left off with refactoring. If you wanted a nice, vague discussion, you could read Wikipedia on Code Refactoring, but you won't find anything you can take home. It would be easier reading the definition, which just quotes the only important part of the Wikipedia article:
Code refactoring is the process of changing a computer program's source code without modifying its external functional behavior in order to improve some of the nonfunctional attributes of the software
So how do you refactor? There are three places that I see it.
First, if you obeyed the golden rule of technical debt, you are keeping track of your loans. Refactoring in this sense is nothing more than finding those areas in your application and working in what needs to be done. It's easy, which is why you need to follow that golden rule. The huge advantage here is that you can put estimates on it and schedule it into your project. This is really more like a budgeted technical debt payment, but it can still fit the refactoring label.
Another path to refactoring is to overcome your knowledge gap. If you wrote a program, you probably did it as well as you could — minus the gaps you know about, but the gaps you don't know about are where your best improvements lie. That's where true refactoring comes in.
I was talking about this the other day with subversively fixing technical debt: reading a book is the best time to come up with new ideas. I guess it's obvious what books I read. The design patterns book was especially great for this. Reading along to tech books sparks all kinds of new ideas. More often, they are unrelated to the content I am reading, not always.
Once you learn what your gap is, and you visualize how to fix it, there is only a matter of time before you get to see it through. This process is why I believe that if you want to have refactoring improvements in your code, (1) you have to be learning, and (2) they almost always come organically.
These organic enhancements like to start deep down in my thinking. Often I read something that produces a small shift in what a good program should look like. Eventually that idea turns into something I can do within my application, like introduce a new kind of object in just the right spot, break a form down into reusable parts, or develop a useful independent API that makes everything feel better. One day I eventually work up a physical understanding of the code that needs to change. I introduce the modification in a safe development branch, then I see if it fits. It usually does, but if not, I roll it back, no damage done.
The last kind of refactoring is incidental refactoring. I do this all the time.
Often while working one programming task, I find ways to enhance things that we never knew needed enhancements. These tend to be little things. Whenever I am in one area of an application I take ownership in, I look around to see if there is anything else I can improve.
Incidental refactoring is the best. It keeps a system fresh, it fixes those little bugs and near-bugs, it is the driving force to cleaning up ugly code, and it makes customers happy.
Incidental refactoring does not happen all the time. There is a single way that I know to produce it, and that way is ownership. You don't plant a tree in front of someone else's house unless they ask you to. You probably wouldn't rewrite a funny loop in a program you have just been introduced to unless you were tasked with it (although I have met a few brazen enough). When you have ownership of an application, you check in capitalizations and misspelled variables. Ownership means caring because the application's customers are your customers, the application's success is your success.
Refactoring is an ongoing process. You work at it and you figure something else out, you think about it more and something new comes to mind. Refactoring is a process, not a task. It's a lifestyle not a goal.