4 ms·
When I develop things I: - Make it work (but good lord is it ugly) - Make it pretty - Make it fast (if necessary) Refactoring is step 2 in this process. Som
by breckinloggins 14y ago
When I develop things I:
- Make it work (but good lord is it ugly)
- Make it pretty
- Make it fast (if necessary)
Refactoring is step 2 in this process. Sometimes I write something and I already know a great architecture for it, so that code is, in a sense, "prefactored". But most of the time I'm solving a relatively new problem and have no idea what I'm doing or how I'll end up coding it. At these times, the "compulsive architect" is at a disadvantage because, in his quest for building things right the first time, he will stare at the IDE and have trouble getting started. That's why I force myself to take the architect hat off and give myself permission to create ugly hacks in step 1.
This same concept applies when I'm adding new functionality to an existing code base. I have to turn off the "but my beautiful architecture!" side of myself long enough to get something working, then remember to turn it on again so my code doesn't turn into a giant ball of mud.
Everyone has their ways of working, but I consider this an important principle of software development. In it, I think, is the reason that "scheduled refactoring" so often fails or, at best, hinders everyone on the team. Programming is more akin to painting or sculpting than to building roads and bridges. It is a deeply personal endeavor and the emotional and practical problems of combining the work of multiple creators into a cohesive whole is a task that should not be undertaken lightly. Ignoring this truth gets you situations like trying to gather nine women to make a baby in a month. It also explains why independent refactoring is often doomed to failure:
- There are practical problems with having the entire code base in such a state of flux. Even with our much-improved merging situation vis-a-vis git, developers will dread merging their work into the radically refactoring branch. This adds a braking effect to the cognitive inertia we try so hard to maintain.
- Refactoring teams dissolve code ownership. The resulting more homogenous code base may tick all the right boxes for management and architects, but it can also (subliminally if not explicitly) tick off the original developers.
- Refactoring is a natural and integrated part of EVERY developers job, one that is best performed holisticaly in context with the rest of his or her tasks. Relegating it to a separate team or denanding that it he performed at a certain calendar time is antithetical to the natural flow of most hackers. Purposefully leaving things ugly so that there's stuff to be refactored later is a soul-sapping side effect of the "refactoring team", especially when the results are metricized.
- The best refactoring happens spontaneously: either an individual developer will say "ok I can't stand how much this sucks one second longer" or a couple of devs will be chatting in the hall and remark how lame the interface between x and y is. These kinds of things usually result in positive refactorings because they stem from an aesthetic desire for beauty combined with a pragmatic quest to remove roadblocks in the code. It's hard to schedule and dictate these "moments of higher truth" in an application's life.
It takes a good team and talented developers to make this all work. It also takes management that understands the need to give developers time to clean up and polish, and that such effort does not, in fact, make the project slower. But then again, a large reason why such an emphasis had been placed on explicit refactoring in recent years is to counteract the tendency for management to throw large numbers of cheap developers at a problem rather than a small group of quality ones. The inevitable mess that results is, sadly but predictably, a titanic for which even the most disciplined refactoring efforts only serve as pumps to prolong the inevitable foundering.