5 ms·
Alternatively, we refactor because the right abstraction for the previous phase of the project is not the right abstraction for the current or next phase of the
by ebiester 9y ago
Alternatively, we refactor because the right abstraction for the previous phase of the project is not the right abstraction for the current or next phase of the project.
While I do have a respect for Chesterson's Fence as a concept, sometimes the answer to "why is it this way" is "we were learning as we went, and if we did it again, we'd do it another way."
I look at it this way: When you look at an older city built before the age of the car, they were built to be tiny to start, not more than a set of shacks. As the town built wealth, the buildings went to more sturdy, to multi-story, and to more ornate structures. Similarly, our code should start simple and dirty, then cleaned up as it has proved its worth, and then refactored to more robust patterns as the code has built the wealth (and demand) to justify it.
We should consider rewrites, then, as a sign of value, rather than as a sign of the previous programmer's failure.
- tboyd47 9y ago> sometimes the answer to "why is it this way" is "we were learning as we went, and if we did it again, we'd do it another way." True, and that's believable when it's people rewriting their own code, but sometimes you'll have people who didn't even try to understand the existing code express a desire to rewrite it.
- pjc50 9y agoI suspect this is as culturally determined as the differing American, European, and Japanese attitudes to rebuilding buildings. European cities typically retain medieval street layout and as many buildings from that time as possible, sometimes even rebuilding to the original style after destructive events. Whereas Japanese houses have a ~30 year lifespan and are routinely rebuilt. And I'm looking up the hill at a castle that accreted between the 12th and 17th centuries. Just as the street layout will outlive the buildings, APIs tend to be extremely durable and intolerant of destructive rewrites. Consider the Python transition.
- dahart 9y ago> sometimes the answer to "why is it this way" is "we were learning as we went, and if we did it again, we'd do it another way." This is true! In fact there's a lot of that, in my own experience. Rewrites are probably most useful on code you wrote, rather than on someone else's, and right when you realize what went wrong, while you're still intimately familiar with the old code. I've watched two different companies follow the "things will be so much better if we rewrite" logic and rationalize large scale rewrites that cost millions, and years, and failed to achieve the aims of doing it better the second time. Rewrites should be considered a sign of value only if we actually learned from out mistakes, only if both everything wrong with the old code and everything right with the old code are well understood. If you rewrite anything substantial before that, you're just guessing, and you're most likely (in my experience) going to suffer taking longer than you want and making the same mistakes again. I've seen that happen to many very smart people. So there's a balance. Rewrites are sometimes valuable, but not automatically valuable. Sometimes rewrites are very harmful. The best chance you have of knowing which one is to read lots and lots of code before you start, to make absolutely sure that the code you're replacing is never being replaced only because the readers didn't understand it or didn't like it's patterns. OTOH, if you have complete test coverage in place before a rewrite, you can freely annihilate and redo large portions of code without having to study too hard.
- tboyd47 9y agoI've seen smart people fall into the following trap: 1. Previous developers did X and X is bad, therefore, their code needs to be rewritten without doing X. 2. Oh crap - turns out, the new code has all these requirements to match the old code's functionality in ways we didn't expect (letters A-W). 3. Okay, so we're doing Y and Z in the rewrite, knowing it's pretty bad, because we didn't know we'd have to do A-W and now we're short on time. Oh, and parts of the code still do X. Now, wait a year for one third of the team to leave because they're rushed, overworked, burnt out, going in a different direction... and another third to get laid off because the project went way over time and budget... 4. Previous developers did X, Y, and Z, and X, Y, and Z are bad, therefore, their code must be rewritten...
- ebiester 9y agoThat's the point of Chesterton's fence analogy: Don't rip down the fence until you know why the fence was put up. I think we're in agreement on this - if you don't have the tests, you don't know what the system does. The Michael Feathers approach is my favored path forward in these cases. Rewrites are more valuable in the small (class-level) than in the large (application-level) in the vast majority of cases. And if you absolutely need to replace an application (say, your company standardized on Oracle and Tcl and you can't hire any new developers because they laugh when you tell them your stack...) you do it piecemeal, building tests in your old system so that you can reliably replicate the functionality in a way that functions as a living, reliable spec. sigh