views:

263

answers:

10

Having read Fowler's "Refactoring" for a while, I still often catch myself thinking "I should have done this in smaller steps." -- even when I did not broke my code.

Refactoring in small steps is safe, but cost time. It's a trade off between speed and risk -- I try to be strategic in choosing the way how I am refactoring.

Nevertheless: Most the time I am doing refactorings in larger steps. If I took some of Fowler's "Mechanics" section and compare how I am working, I maybe find that I often leap two or five steps forward at once. This does not mean that I am a refactoring guru. My code maybe stay for 5 - 60 minutes broken or uncompilable.

Do you refactor in smaller steps and try to produce unbroken code in shorter frequencies? And: Are you successful in doing this?

A: 

I tend to refactor in large steps most of the time so I can see the forest from the trees. It's a "stream of consciousness" kind of programming. As long as you have your last working version safe in your source control of choice...

Otávio Décio
who made you "king of programming"? :b
Dave Ray
geez.. that's the problem with spell checkers, they can't guess your real intention :) Thanks dude.
Otávio Décio
A: 

that's where the "red, green, refactor" approach is useful. At each stage you have the ability to verify that your code's behaviour is unchanged, and the refactoring only has to integrate the new behaviour.

Graham Lee
+4  A: 

I try :) The one urge I have to resist most while refactoring is actually making other changes along the way. Say I'm refactoring some code and see something unrelated in the code. I have to make a conscious effort not to go "fix" that as well. Make a note of it and move on. For one thing, it's a distraction from the task at hand. It also ends up polluting your change set so your commit message now has to document several seemingly random changes.

Dave Ray
A: 

The rule of thumb I use is refactor with tests and only refactor as much code as you are confident too.

At 60 minutes are you certain that your code is doing exactly what it should be. You'd need a lot of tests to pass. I would just try and get one going and then move on to the next.

John Nolan
A: 

If I have a clear picture of what I want to do, and if I can easily verify that I haven't broken anything afterwards, I am taking larger steps.

If the refactoring is more complicated, I try to break it down into smaller steps and do heavy testing after each one.

Sebastian Dietz
+4  A: 

Martin Fowler seems to lean towards the small, gradual refactoring approach. However, after reading his book he does occasionally make some drastic steps but only with unit tests to back up the code.

Refactoring is a controlled technique for improving the design of an existing code base. Its essence is applying a series of small behavior-preserving transformations, each of which "too small to be worth doing". However the cumulative effect of each of these transformations is quite significant. By doing them in small steps you reduce the risk of introducing errors. You also avoid having the system broken while you are carrying out the restructuring - which allows you to gradually refactor a system over an extended period of time. - Martin Fowler

Simucal
+3  A: 

Yes, always. I think the real essence of refactoring is picking which steps to start with.

I find the thing with refactoring large changes in a safe manner is always to have a reasonably clear picture of where you want to go. Then consider your existing system and try to find out which pieces you can introduce that have least likelyhood of being a radical change. Then you can introduce these in a controlled and well tested manner.

So what you do is to work in the vincinity of the nastiness. Not always attacking directly from the front, but sometimes just chipping away small pieces. Usually I wait, and only go for the "big prize" after a few rounds of chipping away at minor nastiness. But I know where I want to go.

The nice thing about working this way is that you can maintain progress. You never "stop development to do refactoring". Arguably there are cases where stopping is the correct situation, but most of the time it's not.

The idea here is that if you "start" with cashing in the prize money, you will be spending the next X days doing the drudgery. And there's risk, maybe you chicken out or it doesn't work - or spend 6 months instead of a week. If you do the drudgery first, cashing in the prize will be possible with less risk. And your code will improve as you go. Sometimes you can decide that doing half the job was enough, since your understanding of the problem increases. Sometimes your idea of where you wanted to go was slightly botched, and you can realign your goal as you progress.

But its tempting to go straight for the reward.

krosenvold
A: 

I usually refactor code as I change it. That is, instead of taking a piece of code and rewriting it while maintaining its function, I rewrite it towards a new functionality and in the process of doing so I improve the design of the code.

Often this means that by the time I've implemented the feature I was after I haven't done a complete and satisfactory refactoring of the old code. It is improved though, and I know I'll have the time to improve it further the next time I'm about to change its function.

For testing this means that I get to test both the refactoring and the new feature at the same time, which should save some time.

It also mean that I only spend enough time on refactoring to improve the maintenance situation required for that particular feature. This should help to avoid over engineering and/or wasting time refactoring stuff that already works and wont benefit from a better desing. By focusing only on code I would change anyway, there is also a high probability I will revisit that code in the near time to do further changes while it's in the users attention span.

John Nilsson
A: 

Small discrete steps is what I'm most comfortable with, though at some points it can be a test of my self-control to reign in what could be a refactoring blood-bath. If I notice any improvements (no-matter how large) that could be made, I make a note of them and consider how it'd be split up into individual refactoring tasks. Plus, having a saga of changes in the commit message doesn't help.

NB. The code-base I work on is quite old, and full of those mystical bugs named after scientists. With large portions still lacking anything near even 50% test coverage it would be careless to get carried away.

gridzbi
A: 

Yep. I like to run the tests continually and so a chain of tiny refactors works well. I get really uncomfortable having my code broken for more than a few minutes at a time, and I generally revert if my code is broken when I go home at night, the re-write the next morning ALWAYS works better than trying to pick up where I was.

Bill K