I typically work with small companies who need to customize software to fit their business practices. A lot of companies have critical competitive advantages embedded in the way that they do things and need to ensure that their software doesn’t get in their way. That typically means that I deal with specific vertical markets (either at the vendor or client level) and dance with 500lb. gorillas to make things work the way companies expect them to. It’s business programming in the trenches and can be nasty, brutish, and, well, not short so much as constrained.
The Typical Battlefield
This is the underbelly of software development. Because the companies are small, being hired is a matter of impressing a very small group of non-technical people—often a single person such as the CEO or President. I’ll sometimes have a full development team, but occasionally I get to do it all myself. That degree of variation means that my methods and opinions have to a) scale well and b) not suck (because I’ll often be implementing them myself).
Because being paid depends on non-technical people evaluating technical work, a lot of really bad things can happen down here. This is where the president’s fresh-out-of-college nephew gets to prove he didn’t waste four years of tuition. Or where that new English degree and some aptitude can turn into a technical career. It’s also a place where developers whose self-confidence exceeds their actual ability can avoid public accountability. For a while.
What that means in practical terms is that I work with small companies who have extraordinary needs and the means and motivation to meet them. It also means that I see a lot of train wrecks (some admittedly of my own making). I’ve found that most of these train wrecks have their origins in one of two fundamental problems.
Over Confidence
You know those eager puppies that get so excited with each person who stops to pet them that they wet themselves? I sometimes see developers who are like this each time they discover a new process, technology, or design pattern.
I don’t fault the underlying impulse, really. Excitement with new technology is typical in IT people for the same reason that air is a common addiction. People who hate change tend to be filtered out of IT pretty quickly. To extend the initial puppy analogy, most developers learn to get by with simple tail-wagging when they find a previously unknown technology that solves a common problem.
What leads to train wrecks are those developers who take off in the midst of their excitement and begin implementing new technologies or techniques without bothering to understand them thoroughly. Like the developer I mentioned in a previous post that implemented n-tier design in each project separately, they may have a vague idea of how the thing is done but they end up with something that is worse than if they’d never heard of the Great New Thing™ in the first place.
If you suspect that you are this kind of developer, stop. Take a breath. Dig deeper. Don’t proceed until you can identify at least two drawbacks and can explain why the Great New Thing™ was invented in the first place. If this is a developer on your team, I’ve heard you can get good results with rolled-up newspapers and consistent, immediate feedback.
A Hammer Finding Nails
I have a daughter afflicted with artism. To her, every surface is an opportunity to improve with color and/or texture. You’ll find developers and architects like this as well—treating each project as an opportunity to improve with their favorite pattern, practice, or technology. This is the opposite of the previous problem because these individuals know their stuff, know it well, and have likely used it successfully before. Indeed, the more knowledgeable the designer, the more prone they are to this particular vice.
The problem here isn’t a lack of detailed understanding of the Great New Thing™, but rather lack of focus on the real needs of the project. Here’s the simple truth: in the world of small business development, a short project delivered quickly is usually better than a perfectly-crafted but more complicated project delivered even a little bit later. In short, It’s a YAGNI world.
I have to be careful here because I’m not saying that any given design principle or practice is a bad idea. What I’m saying is that it is really easy to over-architect these projects. The company has so many needs and can improve in so many ways that it is tempting to go into full framework-building mode and spend months putting something comprehensive together when all that was needed is a basic customization or a specific process.
In some places, I’ve had to pull the YAGNI flag out so often that I’ve considered having a stamp made to save time. Maybe I should make a suggestion to Think Geek.
Keep it Lean
Whether coming from a background of large development or yearning to do so, it is really easy to include things just because they are good design or a "best practice" without bothering to review their actual impact on the current project. The problem is that each pattern, technique, and tool not only commits the project itself forever, it also sets up a barrier for future work by creating a developer familiarity dependency that can be a significant hurdle for later modifications (particularly if a developer only thinks they are familiar with the pattern, technique, or tool).
Each technique, pattern, technology, and design principle should be evaluated in light of immediate need and weighed against future scenarios that include the possibility that you wont be the one doing the work. Indeed, I recommend a slight bias in favor of not implementing a Great New Thing™ because of the tendency of really good developers and architects towards heavy designs that can end up hurting small companies in hundreds of little ways that add up to death by a thousand cuts.
The best "lean" skill a programmer can develop is to program with an eye on refactoring. Moving to something better when it becomes clear that it is needed isn’t a lot harder than if you had implemented it in the beginning (and has the added benefit that you know it is needed) if you have kept refactoring in mind throughout. Leave "quick and dirty" programming for the amateurs. Solid refactor-ready code is the best legacy you can create and one that doesn’t age as people get over themselves or discover some new Great New Thing™.