I wanted to make some changes to the code that generates ongoing (stand by: redesign incoming), and this required some fairly serious refactoring. Refactoring is right at the center of good coding practice; programmers often bend over backwards to avoid it, which is almost always wrong. This theme shows up in the best writing on the subect going back decades, and illustrates an even more central lesson about software development.
Fred Brooks made the key point back in 1975 in The Mythical Man-Month when he said “Plan to build one to throw away. You will anyhow.”
In recent years “Extreme Programming” has (quite rightly) been at the center of discourse about how to make software. XP is actually a bundle of fairly disjoint ideas, most of them good, but which are quite usefully separable. I've always thought that probably the most important was the dogma about implementing requirements: focus on the one or two most important requirements, and get those right, ignoring all the others. Then, when you start work on the next most important, you'll probably have to refactor what you already built, but then, as Fred Brooks pointed out, you probably would have had to anyhow.
And, as I don't think they say explicitly, the refactoring won't be all that painful because having implemented the requirements, you'll really understand them.
And, as I've written before, the only way to really understand a software requirement deeply is to have implemented it correctly once.
Of course, in the real world, sometimes you get your back to the wall and have to put your head down and, for business reasons, implement something to spec the first time. But whenever you do that, you should be aware that the chances are that the spec is wrong or, if the implementation is right, it'll be so brittle that when the spec changes, you're going to have to refactor everything.
But that's OK, you would have had to anyhow.
I think perhaps this is one reason why so much Open Source software is so good; by and large, the functions provided have already been implemented by somebody else somewhere, so they are really well-understood. Programming in the (rare) case where you actually really truly know what you're setting out to build is just a lot more fun and rewarding.