Don’t Design for Reuse

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.

17 Responses to “Don’t Design for Reuse”

  1. John Cowan Says:

    I think your second exception is too narrowly drawn. When should you write a library? The answer is the same as for writing a new application: when the alternatives are too large, too slow, too buggy, too non-standard, too obscure, too unsupported, or too expensive; or require too much glue or are incompatibly licensed, or in some other way are unfit for the purpose. You don’t really have to be an expert in the field to detect at least some of these problems.

    What is more, it’s not reasonable to assume that you are the only one in this situation, so unless you know for sure that nobody (not even your co-workes) will ever want to use any of your code, you should take some trouble to make it reusable, even if that just means documenting the API. (If there’s an existing library without documentation, you might want to document that library instead.) And documenting an API that’s a piece of crap is going to make you improve it, if only to avoid the resulting disgrace.

    After all, if non-library code were never to be reused, what’s the argument for documenting any code at all? Just throw it away and start over each time you have to change something.

  2. Yohan Says:

    What about when you are writing mobile apps or web apps and you are building lots of features that you will want to reuse into 50+ apps later ? 😉

  3. Elliotte Rusty Harold Says:

    Mobile and web apps aren’t special. Chances are if you have something you want to reuse into 50+ apps later, so have 50 other people, and one of them has already written the library you want.

  4. fluminis Says:

    I’m not an expert and I’m always designing for reuse !

    I’m not writing a new library that I will share on the internet. I’m just share some classes with my collegues ! And they do the same with their code.

    Since we work in a company, we do not want to write the same piece of code again and again. So we write code for reuse ! Our small problems are company specific and there is not library out of the box that can do exactly want we have to do.

    By reuse, I mean reuse over and over in the same application, not necessary in an other one. That’s a big difference.

    I understand that I never rewrite code that someone clever than me wrote, test, and support. But for the other part of the code that is business specific, you need to write for reuse as well !

    (sorry for my bad english)

  5. J. B. Rainsberger Says:

    Sigh. The title reads “Don’t design for reuse”, but the point is “don’t reinvent the wheel”.

  6. Peter Kretzman Says:

    Indeed, what J.B. Rainsberger said. The “don’t design for reuse” is overstated and “baitful” here. Let’s put our energy into making sure people leverage what’s out there already, rather than spending energy at discouraging them from what should be obvious practice when coding anything: thinking ahead (within reason) to later use, maintenance, flexibility. Can one overdo it? Of course, but let’s not throw the baby out with the bathwater here.

  7. Fallon Massey Says:

    Wow, where do you start?

    You’re really confused. It’s obvious you don’t design components for iOS, Android, or Windows Phone, and have never done Flash/Flex, Silverlight, or Windows 8.

    I agree that you shouldn’t generalize too early, but it makes a lot os sense to build your UI components with reuse in mind.

    If you’re an HTML developer only, you’re mostly clueless about user controls, since the concept is poorly supported, but in anything modern, it’s a potent concept.

    You may need to do a bit more reading before speaking so broadly(I’m being kind)!

  8. jayunit100 Says:

    I agree, you shouldn’t write a reusable http server. But there are many instances where reusable components are still valuable. Most importantly, a non-reusable component will be exceedingly hard to unit-test, since it might not have the level of modularity needed to run when decoupled from the production environment. Another sort of “reusable” comonent which comes to mind is a domain-specific object or (for the functional guys in the audience) macro or namespace of utilities. These will rarely exist in precise form in prebuilt FOSS libraries.

    A 3rd scenario where reusability is important is when we wish to have uniform developer idioms throughout a codebase. Often times its easier to rewrite a component that exists, or wrap it, in such a way that it more naturally interacts with our API. When we do this, our components need to be reusable.

  9. Fadi (itoctopus) Says:

    The title of the post is misleading as J. B. Rainsberger already stated. I thought you were preaching about a new way that makes development faster by not really caring about code reuse.

  10. Sony Mathew Says:

    My immediate thought was exactly as J.B. Rainsberger. Don’t code for reuse is a “bad” title and “bad” advice 🙂

  11. Reddit Made some stupid snipes Says:

    So r/programming made some stupid snipes at your post and some reasonable comments too (but it’s like panning for gold in a pile of dog turd):

  12. Geoffrey Says:

    “Design for reuse” is fundamentally flawed but I argue that it’s for a different reason.

    Reuse should emerge as a result of good design. What I mean by that is when a piece of code solves a highly focused problem (i.e Single Responsibility) with as few external responsibilities\interactions as possible, then it is easy to reuse that piece of code. The SOLID principles are the principles of design optimisation for maintainability and reuse. Although they are presented with a focus on OO, they apply to any language where the relationships relevant to the principle can be expressed in that language.

    I completely agree with the idea of don’t reinvent the wheel though.

  13. Ted Stein Says:

    Horrible title. Also, horrible post.

    There is a legitimate debate about dependencies vs. reusable code, but not here…

  14. Dave Says:

    Design for reuse is a code smell; design for use instead. If you create something that does a well defined job well, people will (re)use it.

    Don’t assume you know what the future will bring, predicting the future correctly is exquisitely difficult. Of course if you already have requirements for 50 similar solutions, well that’s ‘use’.

  15. Chiro Says:

    It is very hard to write good reusable code upfront – because you just don’t know yet the needs of other people. Trying to predict and satisfy them all is a sure way to hell.
    In my experience, it is best to write the smallest working code, dealing with current issue only. And then, if ever needed, you tweak it to support your current needs also. In a few iterations you will get pretty good reusable code.
    Based on my experience, writing reusable code in first iteration was, almost always, pure waste of time.

  16. Tchoupi Says:

    If I had to push your logic one step further, wouldn’t it become : “Don’t program ! Other programmers can write the program you are going to write better than you do”.

    Or even more :

    “Don’t learn about computers. Young people, born with an iPad in their hands, will get past you soon… Learn management and outsourcing instead”.

    I do think that you need to go through the basics, all of them. Refactoring, writing / thinking about how to write reusable code. Until it becomes automagic. And you master the subject enough to be able to decide
    – when to write code
    – when to spend time making it reusable
    – when to leverage other people’s work…

    Nearly every single developers already implements the logic you describe at a basic level, by not reimplementing the Sine or Sqrt function when he needs them.

  17. Martin Valjavec Says:

    Peter Kretzman said:
    The “don’t design for reuse” is overstated and “baitful” here.

    Yes. Reason: Any function is likely to be called from more than 1 place, so, is this “reuse”? Or just “use”? I have seen code to become less usable since it was designed with params, configs, bells and whistles to make it more “reusable” – for unforeseen “future” use.

    I think, it was in his book “Smalltalk Best Practice Patterns”, that Kent Beck argued, we should make our code usable in the first place before we think about reusability; and we should strive to make it changeable rather than reusable since we cannot foresee, what (currently unneeded!) extra features and parameters (who will test all this?) we need to add to satisfy “future” requests.

    I plead for a small amount of “controls/parameters” in our code to make it more usable, i.e. “short term reusable” in the foreseeable near future … fluminis said it already: even in our applications we do not want to duplicate work, so we need to design for our own use.

    For such case, my feeling is that a “less ambitious” library for one’s own purpose might often be so much simpler than a professional one (for a much larger audience!) – which we maybe should reuse – that the simple homegrown solution can be the better (easier to learn and debug) choice … especially if you can make it so simple that its code is very changeable (as Beck suggested): then it might be easy to adapt it to future requirements as soon as they get known … maybe at least as easy as trying to figure out how the more complex “truly flexible” library functions from the pros can be tweaked by passing optional parameters or setting values in some configuration files.

    To sum it up:
    The most important goals are
    1) simplicity while maintaining correctness
    2) proper design for “current use” (in fact implied by correctness)
    3) a coding style that eases changes in the codebase
    my 2c