Tuesday, August 25, 2009

Framework Misuse: Killed By Friendly Fire


These days there are a lot of really great development tools & technologies at our disposal. I’ve talked about a few of them in the past and how important I think selectively choosing and slowly evolving your technology stack is. While choosing technologies wisely is important, unfortunately it’s not enough. In reality, selecting strong tools & frameworks is meaningless if those tools aren’t utilized correctly. In fact, the right tool used incorrectly is often worse than not using it all. Some of the largest anger tax I’ve paid can be attributed to the misuse of some of my favorite frameworks.

I’ve used weapons as a metaphor for technology selection in the past. That analogy is just as well suited to technology usage. If JDBC is a surface to air missile, Hibernate is the virtual equivalent of an A-bomb. It’s relatively easy to decide that Hibernate is a powerful, industry standard ORM solution and thus identify it as the new standard to replace JDBC on your project. Just don’t make the mistake of thinking this decision constitutes a free upgrade to the quality of your data access layer. Putting that WMD into the hands of developers comes with the cost of making sure they have direction on how to wield its power. The more powerful the technology, the more damage it can do when poorly used.

There’s nothing worse than anxiously arriving on a project only to find that my productivity is constantly being stifled by a misguided attempt to use a great framework. I find myself dealing with things like a "customized" sub class of Spring context that's being used as a Service Locator. Really? We had to create our own version of the Spring context? At this point I'm still in denial, thinking "wow, we must have some really interesting problems to solve on this project". But no, I search relentlessly for the reason regular dependency injection wasn't sufficient and there's none to be had. Someone made a good technology decision and then checked out before doing some research on how to use it and establishing some architectural guidelines. This is a really tough pill to swallow. All of the pieces seem to be in place but somewhere along the way things went awry. You have the right weapons at your disposal but somehow they keep backfiring on you.

In these situations I repeatedly find myself evaluating the opportunity cost of large refactoring efforts. I can’t stop thinking about how great things could be. After some analysis and considerable venting the refactoring approach loses out. I come back to my senses and realize there’s no time in the budget for such changes and that the best possible outcome from a business perspective is that no one will notice the changes. All signs point toward staying the course despite the less than optimal circumstances. That is, until later when I’m once again feeling pain induced by framework misuse and burning mass quantities of time on things that should be simple – things that the framework should make easier. Perhaps I would save more time AND be returned to my happy coding Zen if I just bit the bullet and fixed some of these annoying problems. Wait! I’ve been down this road before. So it goes, back and forth, around and around in a downward spiral toward insanity.

In order to avoid this cerebral tug-of-war, allocate adequate time to investigate your chosen frameworks and identify their correct usage on your project. Most frameworks are very flexible. There are often many ways to accomplish the same task within a given framework. Indeed, extremely "clever" ways even the framework development team hasn’t envisioned. That type of flexibility usually gives developers more than enough rope to hang themselves. In my experience, there tends to be one decidedly right way of solving any given problem with a framework that can be applied about 80% of the time. This is what I like to call “the normal way of doing things”. Take the time upfront to determine the normal way of doing things for your project. This often requires wading through reams of documentation. This may be painful but it’s part of the cost involved with adopting new technology. Identify a standard approach to using the frameworks you’ve chosen and establish some governance to ensure those principles aren’t being compromised unnecessarily. The alternative is to allow development to ensue without direction, naïvely assuming good framework selection decisions will solve more problems than they create. This is a dangerous assumption that is far more likely to have you cursing tools you’d otherwise praise.