A few years ago, I was in a meeting with one of my development teams, and people were discussing their recent contributions. One developer described a class he developed to do something or other, let’s call it the Foobulator. Another developer spoke up, saying, “Yeah, I wrote a Foobulator 3 months ago.” Yet another developer chimed in, ”I wrote a Bidirectional Foobulator about a year ago.” By the time we had finished, 22 of my developers described building a Foobulator with one who claimed he developed a predictive Foobulator with full transactional semantics and a priority queue back in 1943 as part of the Manhattan Project.
Now, it’s possible that this story has become exaggerated in the retelling. It does seem that there were only 10 people on the team and none of them were old enough to have worked on the Manhattan Project. Still, it’s not uncommon to find that multiple people on your team have written essentially the same functionality. Clearly this illustrates a lack of effective reuse.
In the 1990′s, reuse was one of the hot topics for developers. Object-oriented development was adopted in no small part due to the promise of greater reusability. Today, you scarcely hear anyone talk about it. Perhaps it is drowned out by the all of the buzz about agile. But what could be more agile–in a rapid development sort of way–than reuse?
I did a quick Google search for “whatever happened to reuse” and found an article by Steve Adolph on Gammasutra of the very same name from 1999. He defines what he means by reuse and the history of its pursuit. Now, 15 years later I’m asking the very same question.
I don’t feel the need to define reuse beyond saying it is the use of existing designs or code instead of writing something new. You may find articles about reusing variables, data structures, or other entities, but that is not what I’m talking about here. That’s more about code efficiency than programming efficiency.
When considering reuse, there are two key questions to ask:
- Why don’t people reuse existing code?
- Why don’t people write code in a reusable manner?
Reusing Existing Code
In some ways, reuse is more prevalent today than back in the ’90s. The Java Foundation Classes (JFC) and Microsoft Foundation Class (MFC) library provide large collections of reusable code. Along with the proliferation of 3rd party frameworks like Apache, there is more reusable code available. When I was a C++ programmer back then, there were few class libraries that we could use, and we had to write more code ourselves. Rogue Wave Software’s outstanding library, was an exception. It stands in my mind as a shining example of a well-crafted example for ease of use and clean interfaces.
But why don’t people reuse code written by their own team? Here are some common reasons:
- Code is often not written in a reusable manner. Too often, it blends in case-specific functionality with the reusable functionality. You may find that you have to refactor existing code to make use of an existing element. That incurs a cost for retesting the refactored code and any code using it.
- Locating reusable elements is difficult. Even if a reusable element exists, it may be named poorly or placed in the wrong package or library. Our codebases are larger than ever and not as carefully crafted as we would like. So, the number of candidates you may have to consider to find a reusable element is potentially very large.
- Lack of documentation. Even if you can find a reusable element, it may be so poorly documented that you don’t fully understand what it’s doing and why. So, you may not want to incur the associated risks.
- People may not feel that they have time to look for reusable code. Teams are so often under extreme milestone pressure. While it seems foolish to use more time to write something anew when an existing element already exists, time pressure forces people to keep their heads down and focus on things that are under their control, like writing the code yourself.
- A reusable element may require you to alter your design somewhat, which could impose a cost greater than the amount of time saved by using the element.
- Reuse is often not as fun as writing it yourself. Coders tend to be proud and often feel disdain for other people’s code.
- Apathy. Sometimes developers become so detached from the codebase that that they just don’t care about reuse or other architectural and design considerations.
Writing Code in a Reusable Manner
- Writing reusable code takes effort. Whatever it takes to write something for a particular purpose, it takes more to write it in a reusable manner. Plus there is the overhead of properly documenting it. Further you have to find the right library to put it in so others can find it.
- Time. The truth is, many developers can barely find the time to write something for their own use and have no extra time for this overhead.
- Payback. The expected lifespan of code today is much shorter. People may not feel it’s worth the time to write reusable code when the whole thing may be rewritten or scrapped in a year or two.
- Apathy. Again, sometimes people just don’t care.
Even when there is decent code reuse, design reuse is often neglected despite the greater return on investment it offers. Within a project, you may find that screens are implemented following different patterns and often check for different conditions and errors. You’ll have one screen that works well on multiple browsers and another that only works on Chrome and Firefox. Or you may find different approaches to persistence, where code written by different developers handle different errors or make different assumptions about validation.
Not everything we want to reuse can be expressed in reusable classes or functions. Higher level reuse often requires documented patterns, code templates, and snippets. The Design Patterns book is one of the best examples of design reuse. Code templates speeds their instantiation.
At SlickEdit I participated in the creation of a code template system. With it I could instantiate a new set of classes for the Composite pattern in a matter of seconds. The C++ version of this pattern requires 6 classes. That’s a lot of typing! Without templates people often root around to find code that is close and strip out the parts they don’t need. This often leads to bugs from items that were improperly removed or mistakenly left in.
Combating These Problems
Wow! That’s an intimidating list of things blocking reuse. So, maybe we should just give up? I say, “no”! Despite these problems, reuse is important. When done right, it not only speeds our development but creates functionality that works consistently across the application. It also promotes a greater sense of ownership that makes the work much more satisfying.
To establish effective reuse, we need to take an architecture-centric approach to development. As developers, we should all have a clear understanding of the architecture. We should recognize what’s reusable and what’s not and make sure that code is placed in the appropriate place within the package hierarchy. Emphasis should be placed on effective names and clear documentation. All developers are responsible for establishing and maintaining the architecture, not just a chosen few with the coveted title of Architect!
We need to establish patterns and reusable designs. For almost everything we write, there should be an established pattern for how to implement it. If there isn’t, it’s time to define one. If there is one and it can be made better, then it’s time to refine and improve it. One of the most important jobs in our development is to document these patterns and create base classes, templates, and code snippets that help to instantiate these patterns. Ad hoc coding is the enemy of architecture.
If a company is sufficiently large, you could devote people to the collection and management of reusable assets. I see these people as librarians rather than as architects. I really take exception to the title of architect, but That’s A Topic for Another Time (TATFAT). Anyone should be able to contribute a reusable element. The librarians are responsible for making sure it meets standards, is properly tested, and put into the proper library or package so it can be easily located. They may even take the responsibility for documenting this element, which so many developers find particularly onerous. As with a book library, the librarians could also help you locate what you’re looking for.
What about motivating our people? Shouldn’t we offer some kind of bonus for writing reusable elements? No! See my article on The Truth About Money and Motivation. Instead of using money, use the real motivators of purpose and mastery. Make sure that the team knows why this is important and talk about how effective reuse is one of the core skills of great programmers. Most developers want to write good code with effective reuse. Make sure they have the time to do it.
If we’re doing things correctly, almost everything we write should make the next release or next project easier. Effective reuse taps into the passion developers feel for great code, leading to greater creativity and productivity. Besides, how many Foobulators does one company need, anyway?