Agile Zone is brought to you in partnership with:

I have been working in software development for about 25 years as both a programmer and a manager. My passion is software development processes, how to build teams and lead them to success. I am a strong proponent of lightweight, agile approaches, particularly incremental and iterative development. I believe in treating developers as individuals and leading by inspiring. Scott is a DZone MVB and is not an employee of DZone and has posted 4 posts at DZone. You can read more from them at their website. View Full User Profile

Whatever Happened to Reuse?

03.26.2014
| 24506 views |
  • submit to reddit

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:

  1. Why don’t people reuse existing code?
  2. 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.

Design Reuse

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?

Published at DZone with permission of Scott Westfall, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Lund Wolfe replied on Sat, 2014/03/29 - 8:17pm

Reuse is very hard.  It requires design forethought.  Ideally, reuse is discovered in the original design and then it just becomes a matter of maintaining the integrity of the original design.  If the high and low level design is sufficiently modular, then reuse should be obvious.

At the same time, you don't want to design for something that might be reused (but likely not).  This leads to needless complexity, single implementation DI, and an explosion of library jar files.

In theory the standup meeting would lead to discovery of reusable code when a developer says they plan on doing x by way y and another developer says that they already did that.  There is the matter of trust, though.  I may trust some commonly used libraries and frameworks but do I trust the reusable code written by the developer in the next cube ?

We have come a long way in reusing open source libraries and frameworks, but internal reuse is still very hard.

Mario Schroeder replied on Wed, 2014/04/02 - 10:13am

Internal reusable code is also a question of not existing tests, especially when it comes to refactoring. People are scared to touch it, because they might brake something @ the other end.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.