Pramatr Blog

A collection of articles from pramatr.com on technology, security, software and anything we find interesting

Yes You Are Making Changes, But That Doesn't Make It Refactoring!

Posted by pramatr on September 26th, 2008

There are some words in software development that overtime lose all meaning. The more these words are used, and importantly, the more they are used out of context, the more the original meaning is lost. It becomes just one of those words that is fitted into a conversation without even thinking about it. One word that often suffers from this problem is refactoring.

The term Refactoring is widely used throughout software development. Martin Flower is one of the primary documenters of refactoring, and popularised it in his seminal book, Refactoring: Improving the Design of Existing Code. Many people who use the word refactoring however, have never heard of the book and more importantly don’t have a clear understanding of what refactoring actually is.

Refactoring is described as; a disciplined approach for modifying code without changing it’s externally observable behavior. This approach is focused around applying small changes to the code, each of which maintains the existing behaviour. By incrementally applying a number of refactorings, the code can be modified in a measured and controlled manner. Extreme programming embraces this approach with a rule named refactor mercilessly.

Alistair Cockburn wrote; “What we want to express sits in a crack between all the words we possess”, it just so happens that for many people (including myself), one word that is readily available is refactoring.

Team leader: So what are you currently working on?

Developer: I’m just refactoring some code.

Team leader: Are there any particular refactorings that you’ve found useful?

Developer: Yes, I’m refactoring the code.

Team leader: No, I mean specific refactorings e.g. rename method, extract method, etc……

Developer: Yes I’ve been doing all that sort of thing.

Team leader: Have you any idea when you might be finished?

Developer: I’m just trying to get the code compiling again, this might take a few hours.

Team leader: Hmmmm ok, I’m presuming you’ve been reviewing, improving and running the unit tests frequently?

Developer: The code doesn’t have any unit tests, so there’s nothing to run.

Team leader: Do you think it might be a good idea that you write some before you start refactoring? How do you know that your code will work in the same way as it did?

Developer: Errrrr……

If changes are informal or ad-hoc, this might be acceptable, but this isn’t refactoring. If changes will take days or weeks, or the code is simply being rewritten this isn’t refactoring. If the code is just being hacked, this really isn’t refactoring. Changes made in a controlled way are much more likely to be successful, but again this doesn’t necessarily mean refactoring.

Refactoring is in many ways a victim of it’s own success. Many teams have found refactoring to be a successful approach to making code changes in the past, leading to many people discussing all code changes as refactoring. Sometimes this is simply due to a lack of understanding, other times it’s a lack of care and attention for the words being used. Sometimes however people use the word refactoring to give the illusion of making disciplined changes, whilst reverting to plain old hacking.

There is a common perception amongst some teams, that every code change is refactoring, “if you aren’t refactoring how else do you make code changes?” The truth however, is that not every code change is a refactoring, nor does it make sense it to be. Even if the code isn’t truely being refactored, it is still possible to adopt many of the activities associated with refactoring.

Changes made in a structured and disciplined manner, offer far more control and are therefore often far more successful. Important questions therefore need to be asked when changes are being proposed. Are the changes being made with the benefit of a suite of automated unit tests? Is each code change being kept as small as possible? Are the code changes being incrementally applied? Are the changes being continuously integrated? Are the IDE’s tools being fully leveraged to make changes easier? Do other developers understand the approach being used to change the code?

When making changes to code, it’s very difficult to understand the associated risks without a solid understanding of the approach being proposed. If a project is deemed to be too risky it might be postponed and rescheduled for a more appropriate time. To aid understanding within a team, instead of simply using the word refactoring to describe changes, developers need to fully understand the approach they are using. Are they answering yes to the important questions (outlined above), and more importantly, if they aren’t, is that acceptable?

If the actual approach is refactoring, that’s great! It gives other developers some idea about the way potential changes will be made, and the style of approach is well understood. It integrates very nicely with many other best-practices and structured development techniques. This can significantly reduce the potential risks associated with changes, thus helping prevent the introduction of new bugs. But it is also acceptable to make changes that aren’t refactoring, whilst performing many of the same activities. It is therefore vitally important that developers talk about changes in context, and make them in a structured and disciplined manner, regardless of the name being applied to the approach.

If you are refactoring great, if you aren’t don’t be afraid to use a more appropriate word instead!

Motivation behind the post:

Following a few comments regarding this post, I want to clarify the motivation behind it. I’ve known about refactoring for a good number of years, and I’ve also often claimed to be refactoring. Last week I found myself talking about refactoring completely out of context and I was basically playing the role of the developer in the mock conversation. I was claiming to refactor some code, but actually this wasn’t the case at all. Some of the code was rewritten, other changes were unstructured, all without the benefit of unit tests. By telling people I was refactoring, I was giving an impression of control where non-existed, I personally don’t see this as a good thing! In this situation, I believe it’s much better to come clean and admit you are making unstructured changes, and if possible rectify the situation.

Testing without refactoring:

Another point that was raised, was that I had suggested if you don’t have unit tests you aren’t refactoring. I don’t think I did suggest this, but I thought it was worth clarif
ying the point. It is completely possible to refactor without tests, but as many other people have commented, it’s dangerous, it’s scary, difficult and time consuming. This is obviously dependent on the nature of the refactoring.

If the refactoring is a simple rename method, it is typically assumed to be fairly safe. I’ve made this mistake before and broken code when making changes, simply because I wasn’t aware something was called by reflection. I’ve also broken Spring configuration because the AOP used method name matching. Simple changes can still break code, no matter how simple they are!

Refactoring and testing typically go hand-in-hand, verifying the changes that have been made. It is possible to verify this other ways, but if this is a manual activity it can be extremely time consuming.

Related Links:

After writing this entry, I discovered Marten Fowler documented this phenomenon in a post entitled, RefactoringMalapropism. For anyone that’s a fan of the semantic diffusion that Martin describes, I’d just like to add that this was written using an agile blogging technique :-) .

  • Pramatr
    Thanks for the comments, I've updated the post to add a description of what refactoring is, along with the motivation for the post. Hopefully this will clarify my views.
  • TrippleDES
    The article is an attempt to distinguish refactoring from basic code changing, its an interesting read but there is no mention of what can be classed as refactoring, so for those that dont know here's what i think refactoring is:Refactoring is cleaning up code in small increments, from wikipedia "In software engineering, refactoring a source code module often means modifying without changing its external behavior, and is sometimes informally referred to as 'cleaning it up'" I believe the concept is to continously improve the codes design. Its not directly about bug fixing but rather improving the code quality through refactoring implicitly leads to bug fixes.Code cutting, varibale renaming, moving code into appropriate places etc are but a few processes to refactoring.The result of refactoring? Better clean code, readable code, understandable code, easily extendible code, tested code, robust code, efficent code - And a few other things trailed with the word 'code'.Hope that helps someone.
  • Travis
    I absolutely agree that refactoring without tests in place is a dangerous thing.


    While I'm sure the TDD crowd would crucify me for this I'll go so far as to say that this is the main benefit of Unit Tests. So that refactoring can be done with confidence.



    I'm just getting tired of the "elite agile tdd crowd" attitude. Expanding the definition of "refactoring" so that it includes having tests ahead of time seems very elitist to me.



    Thanks for the response though.
  • Pramatr
    @Travis - Thanks for the positive comments, I'm sorry if you were offended but I don't agree with your comments. The reason I actually posted this was that I found myself doing this very thing last week.

    I was talking about refactoring completely out of context, I wasn't refactoring at all, the changes were actually fairly unstructured! I gave the people I was working with the wrong impression and that's really not a good thing! So fess up and admit if your just hacking, people need to know. As for being superior, completely the other way, I know I'm not hence the reason I want to get better.

    If you re-read what I wrote, I didn't say "if you don't have tests you're not refactoring." Refactoring and testing typically go hand-in-hand, as I said in the post, testing is a typical activity along side refactoring. If you look at something like XP then this is very much the case.

    You can refactor and not have tests, you can make changes and not have tests. You do need to verify the changes somehow though, if it's a simple rename method fine, you might not break anything, then again you might. I've broken code before when refactoring simply because I wasn't aware something was called by reflection. I've also broken Spring configuration files because the AOP used method name matching.
  • Travis Laborde
    LOL.


    I guess I shouldn't laugh, but cry instead.



    So, if I perform a "Rename Method" refactoring, yet I didn't have a suite of Unit Tests to run both before and afterward, then it wasn't refactoring, but something else?



    What was I doing then? Just messing around? The method did indeed get renamed after all...



    What's the purpose of a post like this anyway? To rant about how superior you are? I'd say you came closer to just being a jerk.



    I wholly agree with the value of the tests and having a refactoring plan in place. But if I were to try to express those values to others, I don't think I'd say something as completely offensive as "if you don't have tests you're not refactoring."
  • Jeff Eaton
    Mmmmm. I have to admit that it makes me twitchy when I see 'refactoring' summarized by listing the names of canned macros from Visual Studio's context menus.


    I think the idea that wasn't clearly articulated in this post is: "Good refactoring is the process of making an existing, working internal implementation better, while external interfaces are unchanged." Bug fixing is not refactoring. Adding features is not refactoring. And poking at something because you don't quite understand it is definitely not refactoring ;)
  • Bryan St. Amour
    A very good read. Thank you very much for putting together such a great source of information. Honestly, I'm no pro at software development (yet), so I found this very useful to remove some of the fog surrounding the term 'refactoring' :)
blog comments powered by Disqus