Metaphysical Developer

The Failure of Code Reuse

Posted in Software Development by Daniel Ribeiro on September 30, 2009

Using pre-made solutions as parts of solving a bigger problem is a common motif on several areas of human knowledge. At first, it makes perfect sense not to waste valuable time making something that was already done. Encompassing this ideal, a lot has been said about doing this with software, what is commonly referred as code reuse.

There are three canonical types of reusing code, as listed by Erich Gamma and Ralph Johnson: software libraries, Design patterns and Frameworks. There are other kinds of code reuse such as software platform (similar to both a framework and collection of libraries ), services or even using a complete application and building on top of it. Each and every one of these types of code reuse differ in its learning curve, in its flexibility (in the sense of how many different new applications, libraries, platforms or frameworks can be built from it) and the rate of functionality/design embedded in it.

But things are not so simple as putting Lego bricks together. Whenever looking for reusable piece of software, how to pick the most suitable one? Even if there is only one piece of one kind, you still have to figure out if it is suitable, or how much work it will be needed to make it suitable (which is the most common case).

This is because the piece can be too complex, not well documented, not fulfill all the desired properties, not be robust enough, without binds to the language/platform you are using, not have a permissive enough license, not be robust enough or make trade-offs that are not really what you would expect (such as choosing CP instead of CA on CAP), not be supported by a big company, and so on. And this gets a lot more troublesome when you have lots of piece of software to choose from. Since evaluating these things take time, a more agile approach is to make the trade-off of how much time to spend evaluating such pieces in order to gain information on them, in order to reduce the risk of making an inappropriate decision (always weighted by how bad can it be to make one, somewhat similar to swot). Even then, on your core domain, reusing big pieces of code is hardly advisable.

However not all software is reusable. At least not easily reusable. The reasons lies on the difficulties of having a reusable design (such as those stated by Uncle Bob Martin in his SOLID series, or by Neil Bartlett on his Component Models Tutorial) and the fact that making it easy for others to use requires a bit more support (such as documentation, tutorials and/or screencasts). Not to mention that most business are not about launching frameworks or application libraries, and therefore, are not interested in this work (which can be good or bad, depending on the cost of making it reusable, and the money made/saved of doing it). Which ensues that a lot of software is not reusable. All of this could suggest that making reusable bits of software requires a Big Design Up Front. However, agile practitioners suggest making code reusable as it is actually needed (a last responsible moment approach). This has actually worked well in practice, as the framework Ruby on Rails was extracted from other projects from 37 Signals, and Apache Hadoop was extracted from another project: Apache Nutch.

Code reuse is not a simple matter, and should not be taken lightly. It involves decisions that can be more relevant from a economical/business perspective than from a purely technical perspective. In the end, the real failure of reuse is the failure to realize this.

Advertisements

8 Responses

Subscribe to comments with RSS.

  1. PM Hut said, on October 1, 2009 at 3:05 pm

    Are you suggesting that everytime you start a project you write all the code from scratch? I can tell you from my experience in programming that code reuse is something extremely critical in finishing projects much faster.

    I think the problem with re-usability happens when you’re reusing something that was coded by a 3rd party. This usually doesn’t work (code style is different, comments, etc…).

    • Daniel Ribeiro said, on October 1, 2009 at 3:51 pm

      No, i am NOT suggesting that everytime you start a project you write all the code from scratch. Much the contrary. I actually believe we could in fact have a lot more reuse, if people fully understood its benefits and when to make their own software reusable. But making something reusable is expensive, which means that sometimes you should NOT make it reusable. There are tradeoffs. On http://www.infoq.com/news/2009/04/agile-code-reuse, Ron Jeffries discusses some of these trade-offs.

      On the other hand, since most reuse opportunities are 3rd party (let it be libraries, frameworks or any other kinds mentioned before), how to make the evaluation proccess matters. You don’t wanna spend too much time doing the evaluation, as it does not really contribute to the actual problem you are trying to solve, but if you spend too little, you may overlook something important. Again, there are trade-offs.

      About the source parts you mentioned (“code style is different, comments, etc…”): not all code reuse means using the source code. In fact, some fremworks and libraries are not even open source. When the piece of reuse is open source and there is a chance that you will need to change it (either now, or in a near future), then these things become important. Mostly if you are willing to solve potential 3rd party bugs yourself.

  2. Dennis Sellinger said, on October 1, 2009 at 3:07 pm

    While this was an interesting post, I think the first question we should address is “Why don’t we re-use our own software?”. Here we are not plagued by problems of quality, learning curves or documentation (we have what we built).

    Not all software is meant to be re-used. Writing re-usable software is hard and there is rarely ever a guarantee that it will be re-used. Agile development works against building in reuse when there is no immediate payoff. Design methods, such as those championed by Robert Martin are no guarantee of success either (in Clean Code his “good boy scout rule” has him changing public API members whenever he feels it would make for better reading).

    Reusable software has to be written intentionally and usually by people who know how to write APIs. It is hard to get right and once a piece of software is being reused, it resists any changes to the public API. I don’t think it can “just emerge” from agile methodologies or SOLID OO Design.

    • Daniel Ribeiro said, on October 1, 2009 at 4:08 pm

      Nice points Dennis. About “Why don’t we re-use our own software?”: well, reusing a good quality code you, or an integrated team, made is actually much feasible and desirable for the reasons you mentioned. Not all teams actually produce good quality code though. Which is a (much bigger) problem in itself

      On the post I agreed with your point that Not all software is meant to be re-used. But I mentioned pratical frameworks that actually refute your point of “Reusable software has to be written intentionally and usually by people who know how to write APIs.” Sure, when you decide to refactor a part of a project into a reusable unit, you’d better undertand what Erich Gamma says about published API and the outcomes it will have on your project. Not to mention understing the need for loose coupling and flexible design (sometimes, more than in the original design).

      Also, reusable units that are an outcome from a “extract project” refactoring are more pragmatic and refuse the temption of adding more features than needed. Iterating from them, and actually responding to needs of the teams that using it, something very common to sucessful open source projects, allows you to solve initial rough edges. All of these has to do with the fact, stressed out by agile methodologies, that the user’s needs change over time, that the author’s knowledge of the reusable unit increase over time (via user’s feedback or by its own experience).

      But I agree with you: it just doesn’t happen by accident. You have, while being aware of the constraints and benefits, make an active decision. I just wanted bring up some of the constraints and benefits involved.

  3. Rafael Noronha said, on October 1, 2009 at 8:58 pm

    Generally I think you have a problem when you try to build a corporate framework (so programmers can work always on top of the same base).
    Rarely this will bring the expected results.

    Infrastructure is what should be reused, and there are a lot of good vendor and OS options that we can build a software on top.

    Stuff like ORM, web framework, cross-cutting, reporting, everything that is not specific to you core domain probably is already solved and should help you to build software.

  4. Frank Silbermann said, on October 2, 2009 at 11:58 am

    Re-using other people’s code must balance all of the other trade-offs mentioned. The ability to re-use one’s own code depends upon one’s style of programming.

    If your tendency when implementing an algorithm is to use one big method that starts and the beginning and continues until completion, you’re not going to have much to re-use. If you try to imagine future uses of your code, you will guess wrong and introduce wasted complexity.

    But if your style of design is to see the algorithm as the assembly of a variety of smaller operations many of which are are purely mechanical and not necessarily specific to the problem domain, then you will often find it easy to re-use those smaller, purely mechanical operations with minimal refactoring needed. That’s how people came up with utilities such as container classes in the first place.

    With good libraries available, those smaller purely mechanical operations might be easily implemented as messier one-line calls to the re-used library classes. In that sense, your simple more specific method is a facade to the more complex library feature, and your method name is chosen to reveal the business-level motive of doing that specific mechanical operation.

  5. vijaynarayanan said, on October 18, 2009 at 11:54 am

    very interesting discussion. I think systematic reuse is a very hard thing to get right in most organizations. It is possible to achieve reuse with both domain-specific and domain-agnostic assets. However, reuse needs conscious design decisions, alignment with business goals, as well as appropriate communication/brokering within the development process.

    I agree with Frank that it is easier to reuse when you break down a problem into multiple pieces. If we understand the relevant variations in the problem domain we will be better positioned to invest efforts in varying behavior. Without domain knowledge you will end up with big upfront design – high risk of a over-engineered solution, additional schedule risk, and irrelevance to future projects.

    Also agree with Daniel on extracting software to be reusable. I think being pragmatic is absolutely critical. Making software reusable isn’t the same as building it to be perfect, static, and never-changing. You can build only when you have a known application to consume the asset, continuously align user stories with reuse, and delay commitment when necessary.

  6. GmonC said, on November 10, 2009 at 11:14 am

    Interesting topic. Sometimes we see people yelling “don’t reinvent the wheel” without proper analyzing the trade-offs. We have to pay our bills and have the work done, and sometimes it’s better to re-implement something instead of adapting.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: