Adding new functionality to software is really exciting. I love poking around the edges of a system, figuring out what’s going on, and looking for that “obvious” place where the first change should happen. But sometimes, it’s hard to know if I’m making the right change. How Should This Work?
The temptation when changing an existing system is to implement the desired behavior within the structure of the current abstractions. Repeat this without adjustment, and you’ll quickly end up contorting existing concepts or working around legacy behaviors. Conditionals pile up, and shotgun surgery becomes standard operating procedure.
Even if you code test first, you can make a mess of a system. What you end up with is a system that moves from local maximum to local maximum while the time of the test suite grows unbounded. There are worse things that could happen, but no one’s going to jot this one down as a “best practice” either.
The counterforce to this temptation is the red-green-refactor cycle. Look at how the system works and figure out how the next bit of work might change how the system works. Refactor to simplify the act of making a change, or make the change and refactor afterwards to a better design.
Software can grow by accretion, but it stays malleable when the team culture is one that balances continuous growth with continuous cultivation of good design.