Tuesday, March 3, 2009

Reuse Abuse


We hear a lot about this elusive creature called reuse that the entire software development world seems to be in pursuit of. I won’t argue against the idea that reuse is a good thing because in theory it is. However, I think views regarding code reuse are often distorted. Reuse is often perceived as a concept that is so inherently good that it should be pursued at all costs. Because of this, many a software complexity crime has been committed in the name of reuse.

One of my favorite examples of reuse abuse is the “common” project. We’ve all been tempted by the allure of “commonizing” or “genericizing” a large code base into a reusable library at one time or another. On the surface this seems like a reasonable proposal. After all, the code is already written. It’s simply a matter of creating the new project, moving the code and updating existing applications to use the common code. This is a classic “good idea”. Given infinite time and resources it’s probably the right call. Even a separate project plan would suffice. However, it seems these common projects and the refactoring they require are usually appended to the timetable of another project plan or cobbled together in someone’s copious free time. They tend to be side projects, sold under the ruse of being simple matters that will take little time. Perhaps this is because the people selling them believe this ploy. More likely, the salespeople know the primary benefit of such a solution is that it promotes code reuse and that’s a pretty hard sell to stakeholders. When was the last time you got a budget approved for a project that was strictly refactoring? You know you’ll never get dedicated time for the project so you try to squeeze time in for it elsewhere. This is where things go awry. This type of endeavor is a project in its own right. As enticing as it is, if you don’t have the time and resources to commit it’s probably more pragmatic to leave working code alone.

But what about the benefits of removing all of the duplication and only having one code base to maintain? Surely such an admirable goal warrants a rogue pet project. Ah, the temptation of the common project is great. It’s fun work and you can see the grand vision at the end of the tunnel. The draw of designing an elegant, reusable masterpiece tends to magnify perceived benefits and shroud costs. The benefits are real but the end doesn’t justify all means.

Common projects like to create issues of the cross-dependency and build variety. It’s surprising how quickly these non-sanctioned issues can start burning time that was allocated for your “on the books” project. It’s really no fun to explain that you have new issues or are behind schedule because you refactored working code so that all of the applications would share a common code base. Suddenly replacing the old data access code that was working for two years doesn’t seem like such a no-brainer.

From a business perspective, the best possible outcome is that all of the applications will work the same as they did before you started. That should be a red flag. If the biggest upside for the users is that no one will notice you should probably stop right there. Remember: the largest potential downside is something along the lines of “no one can log in”.

You may be betting on the fact that there will be new development in the future that can take advantage of your common code. You could be right, and depending on your level of certainty, creating the common project may be the right call. However, I would tend to defer implementing the common code until I know it’s going to be reused. Gambling your current project’s success on your ability to predict the company’s business needs is a risky bet. Even if you’re correct it’s not very likely you’ll get kudos for being Karnack the architect. It is highly probable however that PM types will be upset when they find out that developers are battling issues with functionality that’s not on their project plan.

At the end of the day, code reuse is good. Removing duplication and refactoring existing code into a common code base is good. However, these efforts aren’t free. Dissecting code and reassembling it into reusable pieces takes diligence. The flexibility it offers adds complexity to overall architecture, especially in the area of build and deployment. Sometimes it’s too idealistic to think that we can implement these concepts the instant we identify an opportunity to do so.

2 comments:

  1. Good call, Chad!

    This issue applies to just about any type of code, grand or small, scripting or OOP. If you get really abstract, you can even apply this to setting generic rules for things such as form design and interaction patterns. If I decide that all submit buttons are X wide and then take the user to a Thank-you page, it's pretty much guaranteed that I'll show up to work the next morning and have to code an exception for a button that can't be that size, or where it doesn't make sense to direct the user to the expected step.

    Also good call about the "best possible outcome" - that logic saves me a lot of time and hassle, and is a key question I ask myself when I am prioritizing work.

    ReplyDelete
  2. Thanks for the positive feedback Bree, I'm glad you enjoyed the post and were able to relate.

    The "best possible outcome" logic is one of my favorites. It does a great job of rooting out trouble buried in those "good ideas" that we like to view through rose colored glasses.

    ReplyDelete