You aren't going to get TimeToDoItOver. So what you have to do is do it over now. When some part of your system gets really crufty and awful, it may well be too late to do anything about it. The refactoring can get so difficult that no one can do it. This happens because the crufty part causes strange code and assumptions all over the system and you can't ever find them all to take them out. (KentBeck teaches that you just find the object that pisses you off the most and try to get rid of it. There are some objects in C3 that really piss me off, but all my attempts have failed. We should have done them over sooner!) What you have to do is to keep the system from ever getting there. You do this by learning not to tolerate pain. When an object is hard to use, fix it right away. Don't just live with it. When you see two methods doing the same thing, refactor them so there is only one. Don't just live with it. This is more than just spreading the cost of a doing it over. Done incrementally in the first system, keeping the space clean will help you go faster and will result in a system that doesn't so badly need to be done over. RefactorMercilessly when you see a problem. It's worth it. --RonJeffries ---- Brooks (?) said "Plan to throw one away. You will anyway." If you throw a big thing away, you get to talk to people about big money for the change, and for the changeover. By doing WorstThingsFirst, YouArentGonnaNeedIt, DoTheSimplestThingThatCouldPossiblyWork, and DoItOverAllTheTime, you throw it away little by little. No one notices, and in fact you go faster than you would if you just lived with it until the Big Rewrite In The Sky. --RonJeffries ---- The hardest part of this process for me is that I always have to be prepared for a simple little task to take a long time. I write the next test case. I look at what it will take to get it to run. Now comes the crisis- I could make it run by adding a flag to the object and conditionals to two methods: elapsed time 5 minutes. Or I could first extract two instance variables into a component to be delegated to, then make the test case run by creating a variant of the component: elapsed time 10 minutes for the restructuring plus 2 minutes for the new component. This moment was the most difficult personally for me as a programmer. It took (is taking) a couple of years to learn to 1) stop and recognize the two options and 2) take the second option because the result is simpler than the result of the first option. It is a decision you will almost never make if you have NotEnoughTime, but you can learn to make if you just have TooMuchToDo. You are counting on several effects to make this strategy pay off: * The costs of restructuring must be low. This will be true if you have simple code to begin with, if you have powerful tools at your disposal (Refactory and GemStone), if you have good tests so your probability of breaking something is low, if you have help restructuring, if you have experience restructuring * The benefits must be high. This will be true if you make further changes like the one you are making now because the next change will be cheaper, if you find common components that reduce the size of the system, if you learn enough about the system to avoid future mistakes or enable future magic --KentBeck