Tuesday, December 25

Wait for the third one-off to build the framework

I have quite a talented and ambitious young crew working for me, and they're always chomping at the bit to show off their skills at using and abusing design patterns. I used to be the same way... a decade ago, now that I think of it. Wow. Give me a second to catch my breath; that knocked the wind out of me.

Now that I'm the stuffy old boss, I have to see the big picture, look out for the greater good, consider long-term goals, and all those other enterprise-y cliches. With that in mind, there's one mole that keeps popping up no matter how many times I whack it: the "let's build a framework" mentality.

We are an ASP. We host a centralized service that multiple clients integrate into their web sites. All of the clients reference the same code on the same servers. Whenever a client calls us up and wants to alter the way a feature looks or works, we have to create a branch in the code to accommodate them. Since all clients call the same code, that branch has to be tested across all clients. These "one-offs" have a high risk factor which increases as we accept more clients.

The way I run my shop, I hand these projects off to my developers to think up a solution and pitch it back to me (before they write a line of code). Rather than acting as the architectural overload, handing down designs like stone tablets, I give them a chance to show me what they're made of.

In most cases, the young whippersnappers use every one-off as an excuse to abstract the discrepant functionality into a full-blown framework. They come into my office and start drawing boxes and lines on my board. Factories here, Inversion of Control there, a sprinkle of Singletons and a dash of Decorators, throw in a Composite for good measure. I sit there quietly and hear them out. Then I ask the questions they dread to hear:

"Is this the first one-off for this feature?"


"Can this be handled by a simple little if-else clause?"


"Do you understand how the introduction of a new framework will complicate testing now, maintenance later, and the learning curve for new hires?"


I remember the countless times I was on the other end of that inquisition. It's tough to swallow. But business and business, and we're not in the business of building cool new frameworks, we're in the business of delivering solid software on schedule. However, there is a light at the end of the tunnel.

Were they to answer the first question, "no, this isn't the first one-off for this feature," then it's a whole other story. Three is the magic number. When two clients want two different behaviors, an if-else branch is sufficient. But when the third one comes along, it's time to start talking abstraction.

Three is the threshold where you need to start asking if these are different variations on the same theme, or perhaps a new theme altogether? How flexible does this feature need to be, or can it be, before you have to break it into different features for the sake of sanity, clarity, testing, and maintenance? There are features in our system which are incredibly abstract, so much so that they differ for every single client. And, there are features in our system where the client's request was so far from the mark we had to create a completely separate version, essentially giving us sibling features that live side by side.

There's a time and place for abstraction and frameworks, but when a simple if-else clause will do the trick, be done with it and move on.


Craig said...

3 sounds like a really good rule of thumb to me. 3 data points is the minimum it takes show a trend (if one exists).

ptmcg said...

Here's a corollary: any framework that only gets used once was a waste of time, money, and precious resources.

I know developers who look back misty-eyed at a dozen-or-more class framework as some of the best work they ever did, missing the point that there was only going to be one application, and that instead of jumping the gun and crafting their ultimate solution of all future like problems, they could have spent their time doing something useful.