in

ASP.NET Weblogs

J e r o e n ' s   w e b l o g

Refactoring is free

I'm a little late to the party, but I wanted to give my perspective on some of the discussion surrounding the cost of refactoring I've been reading about in the past week, most notably some posts by Paul Gielens, starting with Refactoring is Not Free, where he writes:

A couple of months ago we where up for the challenge to refactor a large portion of a badly performing application. The application had no supporting unit tests, cruddy code and Swiss cheese specifications (its developers only had a sense of what the application had to do). It is in this example where refactoring became costly. At start we tried to cover as much existing code possible [...]. Although the confident level increased we weren’t able to preserve the behavior of the code while refactoring small pieces at a time. Eventually we had clear signs that the progress we made just wasn’t enough. We then decided to rewrite it from scratch and than refactor it.

What I don't understand in the described situation is what the goal of refactoring here was. Refactoring itself doesn't increase performance, in fact, often refactorings reduce speed in order to make the design more clear. What I do understand from the above was some kind of decision to just "refactor the whole thing" and then see what could be done with performance, which is a strange approach in my opinion.

When a system performs poorly, there's a basic approach to figuring things out: first find out what the bottlenecks are, find solutions to them, test them independently to verify them in the situation at hand and finally, modify the code to incorporate these changes. Now, refactoring comes along in the final step, because in order to modify the existing code, you'll probably need to do some refactoring. Not all of the existing code, just the pieces where you want to modify things to incorporate the higher performing approach. Now even then, writing from scratch can often be quicker, so the conclusion may be the same. But either way, the refactoring is never "costly", it's always the sanest way to change code. So that's why I'm stating: refactoring is free.

Suppose you have a class that works with a type code that modifies its behaviour. Every method may consist of a switch/case-construct that decides which behaviour to expose. Modifying this into a class hierarchy where polymorphism takes care of the type-specific behaviour does take time, but it's always better than just adding another case-label to all the existing switch/case-constructs. It only takes a couple of 2:00 AM debugging sessions to figure that out.

Comments

 

Frans Bouma said:

I think it depends on how you look at it. Refactoring isn't free when you take into account the initial time to build v1 and add to that the refactoring time to come to v1.1. If you would have written the code which now makes up v1.1 in the first place (so v1.0), you win time, namely you don't have to refactor to v1.1. So in that light, refactoring isn't free.

December 7, 2005 6:28 AM
 

Jeroen van den Bos said:

But the alternative is that you have to do exhaustive requirements analysis up front, which will take at least as much time as the refactoring.

Furthermore, the more software I write, the more I feel that it's usually not possible to know all the requirements before finishing a v1.0 and the only way to get a clear view of what needs to be there is to have something that provides some functionality. So what I do now is just get an idea of what the most important functionality is, build that, let the customer play with it. Then let him pick the next thing that he wants, incorporate those changes (this includes doing some refactoring, as well as writing new tests, etc.) and get the new version to him. This continues until the customer is satisfied (or we run out of money).

I completely agree that if you have all the specs up front, that it's pointless to implement it iteratively. But that's just not how it works (not for my customers anyway).
December 7, 2005 7:26 AM
 

Frans Bouma said:

"But the alternative is that you have to do exhaustive requirements analysis up front, which will take at least as much time as the refactoring. "
That's just an assumption. Those are completely different fields, so it's not said that analysis up front is taking as much time as a refactoring change later on. For example, if you have to make an architectural change to the class model which supports a tiny feature requirement, it can take a lot of time to make that change, while the analysis effort to get that feature requirement can take 5 minutes.

True, it's hard to know up front all the requirements, that's almost impossible. But at least you can try and do the best you can, with methods developed to do that.

Above all, software written is there to solve a problem, or set of problems. By analysing the problem in full, IMHO, the better you know what the solution looks like and thus the less problems you'll have later on to adjust it. However my feeling is that a lot of people lose themselves in developing software just to develop software and forget the reason why the application is written in the first place. I think that's the same reasoning you perfectly addressed with the performance analysis: first analyse the problem, then think of a solution, then implement that solution. And in that last phase you actually touch code. It's the same with writing software (IMHO).
December 7, 2005 7:52 AM
 

Saber Karmous said:

Writing software is a bitch.

I'll give two examples.

The first one is about the art of cutting hair. You enter the barbershop, and ask the barber to give you a nice and trendy looking haircut. The barber asks some questions, and starts to do his job. You directly see what the barber does, and will point the barber on the "mistakes" he makes. If you trust his barber, you'll just sit back, relax, and know what to expect. The confident experienced barber will do his job, and you'll end with a nice and trendy look. Unfortunately in some cases there's some miscommunication. And you'll and up with a very trendy looking green mullet (http://www.mulletsgalore.com/ for examples of some mullets).

Second example. You want a new car. And you know exactly what kind of car you want. You know the color, the engine, how big it should be etc etc. You order it. Then the salesman orders a new car at the factory. For some strange reason we find it completely normal that we don't have any influence on the proces of creating a new car. We do not nag about the color of the rims, we do not care whether the clutch is 10 inches or 11 inches long. We trust the salesman and expect him to sell us a car which is exactly by specs (hmmm real specs, I'm so jealous) and exactly what we expect.


Our "artform" is somewhere in the middle of example 1 and 2. And that makes it a real bitch to live with. Our customers don't know what they want, but it needs to be exactly what they described. Our customers do not want to know how we build it, but they will always want to know what we're doing.

And why do I come up with this comparison. Well the term "refactoring" is a very tricky one, it assumes that we're very good at "factoring" to begin with. And that's currently a complete illusion. Well, I must say to 80% of the developers it is, cause I already hear you scream: "What about TDD?" Yes that comes close, with TDD you should know what you factored cause you're continiously are refactoring. And that way you as a developer are a lot more confident to refactor.

Now there are a couple of reasons to refactor.

- You want the code to be nice an beautiful and full of those elegant design patterns you're evil Java colleague brags about
- For some reason the customer wants something new, and didn't tell you about it (what's new).
- HUH... should non functional requirements be in my code?
- You refactor cause you're the MAN! Heck!, you even have Test Driven Developed you're kids this way...

So there's different types of refactoring? Or the term is mis-used in a lot of places. I think it's the last one. Refactoring to me means that you re-code parts of the applications to meet the same specs/functionality. Refactoring is not something you're customer wants. If a customer asks for better performance means you designed the application to be slow, cause no one told you it needed to be fast, and you need to redesign. And that might lead to refactoring so everything fits again.

So Refactoring could be free if it's part of a TDD proces. It isn't if it's a result of a design change.
December 7, 2005 2:00 PM
 

Jeroen van den Bos said:

Frans: More often than not, customers don't know what they want. It often helps to just build something in the general direction of their requirements and then refine the software based on their feedback. That refining is partially refactoring and partially implementing new stuff.

So yeah, refactoring does take time and in theory it's pointless, but in practice, it's the quickest way to get to a satisfied customer. At least, most of the time.

Saber: Nice rant :-) Personally I feel that there's only one reason to refactor: because you have to modify existing code to incorporate additional functionality it wasn't originally designed to have. Everything else is unnecessary (and yes that means it costs something to do it, but that's more a problem of the developer than of the concept of refactoring).
December 7, 2005 3:55 PM

Leave a Comment

(required)  
(optional)
(required)  
Add