Last week one of my colleagues hit me with an idea that was so obvious when he pointed it out I wondered why I hadn’t realized it before:
If you’re designing for reuse, you’re doing it wrong.
In 2012 the only code you should be writing is what’s needed for the immediate task at hand. Don’t design for reuse. Don’t consider reuse. Don’t waste one minute of your day making code reusable.
The fact is any reusable code you need already exists. Want to connect to an HTTP server with full support for authentication and cookies? That sounds like something a lot of projects could use, so you should wrap it up in a nice HTTP class or library, right? Wrong. You should use Apache HttpClient instead.
Do you need to solve some initial value problems with a shooting method? Don’t crack out your numerical analysis textbook and start coding. Just download Flanagan’s Java Scientific Library or buy a NAG license instead. Need a date chooser widget and want to share it with your colleagues? Just tell them about JCalendar instead. Maybe that doesn’t have exactly the look and feel you were aiming for? Fair enough. Write your own component or fork the existing one, but realize that your very specific look isn’t likely to fit other people’s apps any better than JCalendar does, so don’t waste any time making yours reusable.
These examples are for Java, but the same is true in any major language including Perl, Python, Ruby, C++, C#, and Scala. In fact, if the language doesn’t have a library that solves the reusable parts of your problem, you shouldn’t be using that language for that problem.
Are there exceptions to this rule? I can think of two (and so far this feels like an exhaustive list).
The first exception is when you’re writing code for something so new that libraries don’t exists yet, and you’re the first one out of the gate, then make the code reusable. For instance, when I first wrote my XIncluder libraries the XInclude spec was still in development, and there really weren’t any alternatives in Java. These libraries became part of the proof of implementability that allowed the spec to advance to full recommendation status some years later. (That effort very nearly got me condemned to invited expert status on the working group, though fortunately saner heads prevailed.) Writing my own XInclude library made sense ten years ago, but I certainly wouldn’t repeat it today.
The second exception is for experts only, and I’m not even sure about this one. If you really are an expert in the field that the reusable code addresses, and if you have made a careful survey of the existing options and concluded that they are inadequate and you see how to do a better job, then, and only then, might you consider writing your own reusable code. This is what I did with XOM. Only after I had written a several hundred page book exhaustively documenting all the then current APIs for processing XML with Java and their stengths and weaknesses, did I sit down to design an API that improved on them. And although I do think I came up with the best such API yet designed, I’m still not sure that was the best use of my time. XOM is, IMHO, superior to what came before it; but it hasn’t been superior enough to really replace those other libraries in many applications. The need just wasn’t that great. As time passes, the code already available for reuse approaches “good enough” and the cost/benefit ratio of improving on it goes way up.
Are there other exceptions? Other times you really should write reusable code? I can’t think of any. Too many developers have spent too much time exploring the problem space, and made their work available for free at sites like Sourceforge and Github. While there will always be new problems to be solved, there’s just not a lot of benefit to be gained by solving the old problems one more time. The next time you find yourself designing for reuse, stop and ask yourself whether you should be reusing someone else’s code instead.