From ThoughtfulReactionsToXp:
The image that this puts in my mind is of someone one day declaring 'Look lads and lasses. The code's got a bit out of shape. Let's spend a week refactoring'.
Refactoring done correctly occurs as a continuous part of the process and is automatically controlled by the scope of your current EngineeringTask/UserStory and is performed as a part of implementing that EngineeringTask/UserStory.
Your product is delivered incrementally with timescales defined at the beginning of the cycle so you should not be in the 'let's hack it to get it working and deal with the rubbish later' mentality that you tend to get into when you (or someone else) decided your timescales nine months ago with a completely different set of requirements.
-- LanceWalton
process: aRecord (self shouldMap: aRecord) ifTrue: [self map: aRecord]Done. No need to revisit. It always turns out that way. There is no looping in improving the code.
You don't work with the non-XP code that I do. I could refactor for a solid month and not be done. -- JeffGrigg
Where do you draw the line when it is time to deliver? I have always heard that you do it when the number of bugs flattens out ( or disappears ). With tests it seems to me that I am always in a good position to release my code. Because I can prove that ItWorks.
I'm new to XP (reading about it for a week) and I feel I am completely missing the point about refactoring. So, I'd like to ask some blunt questions.
Direct Answers to Wane's questions:
1) If the code is working, why in the world would I want to rewrite it?
There are a lot of reasons you might want to rewrite a "working" piece of code.
2) How would I even know to look at a file to decide to rewrite it?
A: The CodeSmells
Or, put another way, you see that the code could have been written a different way, and if it had been, it would be better. So you change it to be that way. Now it's better.
3) If I am tracking down a problem, wouldn't rewriting the code potentially mask the problem, especially if it needs to be fixed in a higher or lower layer?
If you're tracking down a problem, looking for the cause of a bug DON'T CHANGE ANYTHING!!! ...until you find the cause of the problem.
Refactoring won't fix a bug, because refactoring (along) does NOT change the functionality of the program. But refactoring the code make leave it in a state that makes it a lot easier to fix the bug.
So (1) find the bug first. Then (2) write a test that exposes the bug. Then you can (3) fix the bug and finally (4) refactor.
Wayne asked, "If the code is working, why in the world would I want to rewrite it?"
There are two ways you can read this statement:
Code that has been properly refactored is a breeze to modify. And when you modify it, you then refactor it, so it's still a breeze to modify.
Refactoring can be risky if you don't have a full set of UnitTests in place, along with "the whole nine yards" of XP process. Therefore, until you have the rest of the process in place and running smoothly...
Now the most common maintenance approach is to make the absolute minimum change required in the program to accomplish each change request. However, this is foolish: Such "quick fixes" have a high probability of introducing further bugs, and will quickly add up to make the program very difficult to maintain.
A better approach is to keep your eyes open while doing routine maintenance, and improve any code you happen to be working on. If a refactoring of surrounding code will make this customer-required change easier, do it. Add comments. Change a few variable names to make their intent clearer. Extract repeated code into a subroutine/function.
This approach does not significantly increase risk, even if you don't have a full set of regression tests in place: Even if you were to do the customer-requested changes with a "minimal code change hack," you'd still have to test it thoroughly; same goes for any minor refactoring you do at the time.
You may be surprised: A few months of "underground refactoring" can dramatically improve the reliability and maintainability of a system - even to the extent of being visible to management. [ExtremeProgrammingInEnemyTerritory]
I think we can develop some useful guidelines by examining the EconomicsOfRefactoring
Contributors: JeffGrigg
I would say 'If I am tracking down a problem, rewriting the code would clarify the problem.' The point is to improve the structure of the code such that it is easy to add new functionality and (hopefully) easy to reuse the methods elsewhere. For me, increasing the clarity of my code drastically improves my understanding of it. If you understand PythonLanguage, I could show you several refactorings that I've done, or you could check out this recently documented PythonLanguage refactoring: http://www.sabren.com/rants/2000/05/20000526a.php3 -- ShaeErisson