A recent discussion on the Extreme Programming Yahoo Group explored the apparent conflict between making software reusable and the XP practice of not writing code until it is needed. Ron Jeffries and others shared insights about the costs and benefits of code reuse, as well as how and when to do it in an agile environment.
Brandon Olivares started the discussion. He had just put 30 hours into some code and felt that it had potential to be reused. He was feeling conflicted about whether or not he should generalize it so that other projects might be able to use it.
As far as I understand it, XP discourages assuming something is going to be needed until you actually get to that point where it is needed. Also according to my understanding, that includes abstracting code to be more general for reuse, until there is duplication, and then it can be refactored.
Software reuse has long been touted as a great time-saver. Perhaps developers on another project could benefit by reusing his code instead of having to reinvent it. Brandon asked the group members how they decided when to abstract and generalize code, so that other projects could make use of it.
Ron Jeffries was the first to respond, outlining some of the reasons why reuse across teams can be more difficult and expensive than it might seem at first.
I have to do work to package it that I wouldn't do for myself; I have to document it; I have to make it more bulletproof, removing issues that I just work around automatically; I have to support it and answer questions about it; I have to train people in how to use it.
If I do those things, it's expensive. If I don't, using my stuff is difficult for others and doesn't help them much.
All of this leads Ron to approach the topic this way:
I build the abstractions I need. If I need it again, in a slightly different context, I would improve the abstraction. But unless my project's purpose is to build stuff for other projects, I try not to waste any of my time and money building for other projects.
Another poster observed that reuse can be facilitated by all of the projects sharing a common build system, and a unified set of tests. In this way, a team that wants to reuse some code can generalize it to fit their needs, and the build and test system will help ensure that they haven't broken anything for other projects that use the code.
George Dinwiddie, Ralph E. Johnson, and others recommended generalizing upon second (or even later) use. Adam Sroka called this 'emergent reuse' and noted that this seemed more efficient than the 'design for reuse' approach. A poster named Tim explains it to his business people this way: "The first time you have to pay for it to be coded, the second time you have to pay for it to be reusable, the third time it's free."
George pointed out that the more difficult problem might be how to make other teams aware of potentially reusable code. The cost of the communication necessary for useful discovery can be significant. Jeff Langr suggested that having developers pairing across projects could be an effective way to address the discovery problem.
Scott Ambler joined the conversation, pointing out that open source is a form of reuse that has been very successful. He also noted that code libraries, development kits, and even mash-ups are examples of software reuse that works.
Adam followed with this observation:
It is important to distinguish when my team uses what my team previously used vs. someone else some other time. The latter generally requires more forethought... even for someone outside my team to be aware of it. There is a cost to that, and that cost better yield some business value
How do you decide when to reuse code? Leave a comment and share your opinions and experience.