ArticleS. TimOttinger.
DontRefactorEverything [add child]

Do Not Refactor Everything

Don't refactor all your code. I know, I know, you've been told to refactor everything, and always drive your design from the refactoring. Yeah, yeah, yeah. People stress out over this kind of talk and tell me that it's unreasonable and unilateral and stress-inducing. It's radical. I am known for making a few oblique statements myself, and I am aware of the stress it produces in the onlooker. I almost feel sorry for them in softer moments.

This is one of those moments.

Let's be reasonable. It is logical and obvious that you only need to refactor code in order to make it easier to read and/or change. If you don't have to read or change any particular bit of code, then refactoring might be interesting and might yield some good effects in general (yadda yadda yadda) but it's not really important. Old code that is feature-complete and stable is not our issue. So let's forget about code that doesn't need to change. Really. Just take it for granted and move on with your life.

There are two situations in which code is likely to change.

The first case is that of newly-written code. If you write something new (class, function, module, line of code), it is likely to have some kind of bug or shortcoming, and it's likely to have functionality admendments in the near future. We need to make that code clear, obvious, and easy to handle so we can fix it. Users may decide it's not what they really want so we may have to delete it. Let's keep that option open, too. We can clearly not refactor old stuff that doesn't change, and we clearly must refactor the new code sitting in front of us.

The second case is that some code stays "new" in the bad way (accumulating changes) without staying "new" in the good way (simple and clean). If you look at any version control history, you can see that there are at least a dozen files that keep being checked out and checked in with changes. It is normal for any code base to have a few "hot spots". Change history is a pretty good predictor; the more things change, the more reasons they have to change. Any such code needs to be refactored to make it easier to modify and extend as time goes on. Not refactoring such code is just asking for trouble.

There you have it. There are only two conditions under which refactoring is necessary (both are really different cases of "new stuff"). You don't need to refactor everything. You only need to refactor all of the code you actually work on.

Late Breaking News

My friends have convinced me that there is situation #3: The collateral change -- when you are working on A, which interacts with B and B is awful. This is like stepping in a cow pattie on the way across the pasture. Once you've stepped in it, there has to be some cleaning up. So now the list has changed.

  1. New things you are adding
  2. Old things that you are changing
  3. Old things that otherwise get in the way of #2, above.

So only these things should be refactored. Now don't you feel better?


 Thu, 28 Sep 2006 01:00:08, Jim Weirich, Refactoring for Understanding
I will confess to occasionally refactoring code to understand it.
 Thu, 28 Sep 2006 06:10:11, Erik Koerber, Refactoring for uniformity and maintainability
There's at least one more situation where I refactor: when I see the same kind of functionality implemented in different ways and I know there is more of it to come. I take the time to analyze the existing implementations and decide which (if any...) is the "right" one - then I successively adapt all existing implementations (not necessarily immediatly - a lower level thread also does it...). I see this as an investement in maintainability - and also as a help for the team as it is quite annoying to find four or five different ways to do the same things: it often leads you to invent one additional that is a mix of those you liked/understood best...
 Thu, 28 Sep 2006 18:33:31, Tim Ottinger, Curious
I wonder how you manage to see code you're not working on. If you're preparing to change code, then I suggest you're in my second case.

Or else you're trolling for things to improve, or your organization has asked you to review some code ... heh, little did they suspect that you would review it by refactoring it (which I recommend and admire)!!!
 Fri, 29 Sep 2006 07:28:45, Erik Koerber, Seeing code I'm not working on...
How I manage to see code I'm not working on?
1) When I'm beginning to implement some functionality in a part of the project I'm not so familiar with. I try to find how similar functionalities have been implemented in the past. If I find different approaches in the code, I ask colleagues who are more experienced in this area why this is so. Believe it or not: more often than not I get the answer that this was first done this way, then that way, and well, we know we should rewrite it this or that or some other way, but there was no time etc. etc.
2) As we all know reading someone else code is a very good way to learn - even it is sometimes a way to learn how not to do things.
3) Code reviews.
4) There is also a maybe less "conventional" tendency of mine that I would try to "sell" as "code hygiene": I just go through some random part of the code (sometimes based on metrics - long classes, methods with high complexity etc.) and "inspect" it. And then... well if I find "horrific" code, I think once, twice, possibly thrice and then I refactor it (after having written some unit tests if none are to be found...) or I leave it (for the reasons you mention, or because the risk seems too important/difficult to weight). Note that I have a far better feeling when I do the refactoring than when I don't - leaving smelly code unchanged is to me very much like not emptying the garbage can or not cleaning a wound, it's unhygienic and this lack of hygiene can hurt the software very badly
So I'm finally outing myself: I don't actually agree with you that we shouldn't refactor everything, as far as I'm personally concerned, though I consider your advice to be wise in general :-). But I'd need a blog entry of my own (maybe more than one) to explain why I think this way...
 Thu, 5 Oct 2006 17:41:29, Jon Skeet, Another situation
Tim wrote: "I wonder how you manage to see code you're not working on."

Consider the situation where I'm working on component A, which makes calls into component B. Something in component A isn't working as I expect, but I need to debug into component B in order to find out what's going on. Looking at the code for component B gives me the shivers, and costs me time to understand because it's so nasty.

At that point I'm seeing code I don't actually *have* to change. I may have no real requirement to change component B - but refactoring it to make that debugging/understanding exercise easier the next time is at least a reasonable possibility, IMO.
See above modification - Tim