A Maturity Model for Software Asset Reuse
Code reuse, and especially object reuse, is not a new topic. Software professionals have been talking about reuse for decades, but somehow true reuse still eludes virtually every organization engaged in software development. Scanning through the literature on reuse one can find plenty of articles on the benefits of reuse and even quite a few sources on the best object-oriented design principles that lead to reuse. What is missing in the literature are success stories, as well as practical advice on making reuse a reality within your organization.
This article is based on first hand experiences implementing reuse practices and strategies at companies such as Alamo Local Market Division and FedEx Custom Critical. We will start by exploring what we actually mean by reuse. Next, we will provide a reuse practices maturity model that you can use to gauge progress within your own organization. We will conclude with an overview of the specific practices and tools that we have used to implement reuse practices and strategies.
What is Reuse?
Almost everyone I talk to has a different idea about what constitutes reuse. For example, if a developer copies a source file from one project into another project, is that reuse? How about if the developer copies a compiled class instead of a source file? My point is not to state that one view is correct and the other incorrect but to merely to point out that there are many kinds of reuse. And if we are going to make any true headway in the practice of reuse we must understand these different kinds of reuse, including the repercussions. To this aim I would like to suggest the following Reuse maturity Model.
Reuse Maturity Model
The following Reuse Maturity Model is based on experience within my software development organization, as well as experiences with and observations of other development organizations.
Level 1 - Single Project Source Based Reuse
Organizations at the first maturity level place all their source code within a single project. Very often this single pool of source code will hold multiple applications. This situation is depicted in figure 1.
Project A is home to two applications: A and B. This practice totally sidesteps the above question of whether copying a source file from one project to another project constitutes reuse. There is simply no need to copy source files or compiled files from one project to another because there is only one project.
Figure 1. Level 1: single project contains multiple applications as well as their common code.
Of course, there is a limit to how well this practice will scale. Once the number of applications or the number of developers increases, maintaining a common pool of source code will become increasingly difficult.
Level 2 - Multi Project Source Based Reuse
The next stage on the reuse maturity road map is to separate the source base into multiple projects (usually the project boundaries will correspond with the application boundaries) and practice source-based reuse between the projects. Source-based reuse in this scenario entails copying the source developed in one project into another project. The prime targets of such reuse are utilities, which were originally developed in one project but can be used in the next project. This situation is depicted in figure 2.
Project A is home to application A and project B is home to application B. The code common to both projects (depicted in orange) is copied into both projects.
Figure 2. Level 2: one project per application, common code copied into each project.
The problem with multiple-project source-based reuse is that after being copied, the reused source code has no link back to the original. This causes all sorts of maintenance problems, since bug fixes will have to be applied to every project that reuses the copied code (something that will never happen in practice). Also, as the two host projects evolve the reused code will evolve with them, making maintenance even more difficult.
Level 3 - Ad hoc Binary Reuse
Ad hoc binary reuse is the next step along this maturity road map. Organizations advance to this level after trying multi-project source-based reuse and realizing the drawbacks of that approach. Under ad hoc binary reuse, project boundaries realign and no longer mirror application boundaries. Projects at this maturity level can correspond to applications or to reusable components. The utilities source code that was copied from project to project at the previous maturity level is now placed in its own project, and has its own lifecycle independent of the application projects.
The application projects include the binary artifacts of the utilities project, and a dependency relationship between the projects is established. Maintenance of the utilities project is greatly simplified because rather than maintaining multiple diverging copies of the utilities, only a single version needs to be maintained. As an application requires additional features of the utilities, those features can be added to the utilities project. This way the additional features become available to all applications using the utilities (figure 3).
Figure 3. Level 3: Reusable components/libraries are their own projects.
But at this maturity level there are no release procedures or dependency management procedures. Whenever new features are required, they are added to the utilities project, the project is rebuilt, and the resulting artifacts are placed in the application project. This makes it impossible to know what exact version of the utilities project is being used by any application project. And that makes it impossible to know whether a new feature made the library incompatible with the other application projects already using the utilities. Also, when a bug is discovered, it is difficult to know what version of the code base contained the bug. After a fix is implemented, it is difficult to know whether the newest version (the one that contains the fix) will be compatible with all the application projects that need the utilities library.
Level 4 - Controlled Binary Reuse and the Reuse/Release Equivalence Principle (REP)
Controlled binary reuse builds on ad hoc binary reuse. The project boundaries remain the same, with application projects and component/library projects. Where this maturity level differs is in the process for versioning and tracking the releases of projects. At this maturity level, each release of a project is controlled and tracked with a version number.
At this level, when a bug is discovered within a reused component, the exact version of the component with the bug can be identified. The dependencies between projects can now be tracked explicitly as well. For example, we may know that application A requires version 1.0 or higher of project C, whereas application B requires version 1.1 or higher.
Finally, this reuse maturity level embodies the Reuse/Release Equivalence Principle first made public in 1996 by Robert C. Martin's C++ Report. The principle states: "The granule of reuse is the granule of release. Only components that are released through a tracking system can be effectively reused."