An Agile Approach to Code Reuse
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.
Which kind of code I reuse
Like in spring way
Example of successful reusable code are Spring Framework, Java API, and some thing like that.
To achieve that, it must be common code, well documented(javadoc), have reference documentation and some tutorial, just like Spring and Java.
Reuse and coupling
That is, assuming you reuse code in binary form (jars, dlls, etc.), across different projects. The most widespread form of reuse, the 'cut-and-paste technique' doesn't have this problem. It's interesting, though, that cut-and-paste have such bad reputation :)
Reuse and agility can go hand in hand
When is reuse feasible?
Refactoring and authority
- When duplication is scattered across different projects, it can only be removed by a person who has the authority to commit changes to (at least) three different projects - that is, two real-world applications and one library.
- A person responsible for library design can always try and create a Very Smart Framework, but it has all the risks and drawbacks of so called "big design up front". I find that most people are reluctant to use the new functions somebody has written for them.
- Another approach is to provide people with the authority to change code across several projects. Personally, I like the approach described in one of the earlier articles on InfoQ: www.infoq.com/articles/scaling-lean-agile-featu.... But I have never had the opportunity to work in that kind of environment - it might turn out to be not so good as in theory.
Reuse should be cheap
Anyway, code reuse is just a part of more conceptual problem (software knowledge reuse), and it's a good question how to organize our technical knowledge in simple and reusable manner. I think that model driven development is a good answer to this question (you may be interested in my open-source project NReco where I've tried to organize effective first-time reuse).
Reuse as a Cultural Value
My conclusion is that to make a significant increase in the success rate of reuse - there has to be a fundamental change in the organization's behavior reward system. Reuse needs to be affirmed as a valuable behavior - by correlating it to compensation - and metrics for promoting and achieving reuse need to be embedded into the performance review process.
Two examples of attempts to improve reuse in the government sector include the following:
The Component Organization and Registration Environment (CORE.gov):
Core.gov provides a collaboration environment for component development, registration and reuse. CORE.gov began operation in March 2004. Over time, it will become a networked community of component developers and reusers and will offer numerous components of various types and complexities, including business components, e-forms and technical components.
CORE.GOV grew out of the Federal Enterprise Architecture (FEA) Project Management Office, the goal of which is to support cross-agency collaboration, transformation and government-wide improvement. CORE.GOV offers an environment where component developers and reusers collaborate seamlessly and easily.
Another potentially useful reuse communication mechanism that is domain-specific to the government transportation industry is the Transportation Research Board's (TRB) Research In Progress (RIP) Database: rip.trb.org/
The Transportation Research Board's Research in Progress (RiP) website contains the Research In Progress (RiP) Database and a data-entry system to allow users in State Departments of Transportation, the U.S. Department of Transportation, and University Transportation Centers to add, modify and delete information on their current research projects. The RiP database now contains over 11900 current or recently completed transportation research projects. Most of the RiP records are projects funded by Federal and State Departments of Transportation. University transportation research is also included. The RiP Database now serves as a clearinghouse of University Transportation Centers ongoing research.
These two examples are not perfect by any means - and are insufficient without a corresponding change in an organization's behavior reward reinforcement mechanisms.
My preferred approach...
The first time you need it, you just build it.
The second time you need it, you build it with an eye towards reuse, but don't worry about getting it right for reuse.
The third time you need it, you build it fully for reuse. By now you should know what is common to the functionality vs. what's specific to a given app/implementation.
I've often found the things that I think I'll reuse, I don't. Subtle differences in requirements can make all the difference.
Test coverage for reusing across team
Also the tests around the utility itself will serve as a documentation for the utility.