Internal Code Reuse Considered Dangerous

The title of this entry is intended to be a bit controversial.

Controversy is required, as one of the thing that I’ve noticed in this industry over the years – especially as it tries to shape up and professionalize to combat offshoring – is the large number of otherwise brilliant people desperately clinging to whatever looks like best practices. Traditionally they would be called cargo cultists.

They want to look the part to the greatest degree possible, doing a good job where they can, but ensuring that no-one can question their decisions because they’ve deferred all rational judgment to the beating mantras of “industry best-practices”. Patterns, code-reuse, frameworks, struts and MVCs, CRUD, n-tier, web services, process, and so on. I’m hardly the first to observe it, but in a couple of very large corporations I’ve watched whole divisions pursue efforts that everyone (and I mean everyone) knew would be detrimental in every way that they were supposed to help, but people were happy as long as it covered their behinds in the case of questions from higher up. This isn’t just a culture of yes-people, but rather one where people will happily pursue activities that give the illusion of best practices, without ever questioning or understanding why it’s a best practice, or whether it’s really a best practice in their unique environment or niche.

One such “best practice” (there are many that I’m suspicious of, but I should probably keep this entry at least remotely focused) is the tendency of teams to accumulate, and advocate the reuse of, internal code. This is often done under the banner of frameworks, common libraries, component sets, and so on. The idea is that with this accumulated quantity of code, each new project will have a leg-up on the competition. Code in the library is considered an asset, and managers and owners like the idea that, while developing product A, as a side effect they’re accumulating this great repository of generalized code which they’ll be able to use for a completely different product – let’s call it product B. Soon the domain knowledge of their developers won’t matter (and thus they’ll be expendable), because everything is encapsulated in common code: They’ve codified the abilities of their team.

This couldn’t be further from the truth.

The greater the bulk of code you accumulate, the more intrinsically you tie yourself to your current developers (and the more they occupy their brain with information that is only applicable in one organization or team), and the more difficult it will be to bring new developers online. Such frameworks and libraries often come with enormous learning curves for new hires – especially as documentation is virtually always ignored – and they can seldom be reused for anything else without significant refactoring (because they likely weren’t truly designed for reuse, or they were in only the most arbitrary and superficial of ways. I think every developer can empathize with being told that they could “just use our library X to do that”, to find that it offers nothing remotely like the promised functionality, so the developer is then tasked with not only building the functionality, but building this single-use functionality in a manner consistent and generalized for the library, despite it being unlikely to serve any purpose for anyone else, ever).

The question every organization needs to ask itself, then, is what value they could sell their “reusable code” for – what, realistically, would competitors and new entrants in the field offer for it? The answer, in almost every case, is $0, and they wouldn’t want it even at that price. There is extraordinarily little code theft in this industry (even though we’re in the era of burnable DVDs and USB keys) because most code – above and beyond the industry-wide frameworks and libraries – has no value at all outside of a specific project with a specific group of developers. Trying to use it for other projects is often worse than starting with nothing at all.

Perhaps I’ll augment these thoughts, and refine them further, in the near future, but a couple of bullet points should convey the basic premise.

  • We all believe in code reuse, where appropriate, but it isn’t an all encompassing mantra. It doesn’t make you a better developer beating your chest with empty statements about code reuse
  • Code reuse doesn’t happen by accident, or as an incidental – reusable code is designed and developed to be generalized reusable code. Code reuse as a by-product of project development, usually the way organizations attempt to pursue it,  is almost always detrimental to both the project and anyone tasked with reusing the code in the future
  • Internal code reuse for niche industries and domain specific problems can be very valuable, but code for generalized, industry-wide problems are seldom valuable unless you’re truly developing it for industry-wide consumption (e.g. the .NET Framework is tremendously valuable code reuse). I have seen too many examples of large internal libraries that are largely duplications of vastly superior functionality existing in the .NET Framework or C++ Standard Template Library, or which could be better served by available professional or open source libraries. If your problem isn’t domain or niche specific, but rather is industry wide, it is extremely likely that either a library encompassing it exists, or that it isn’t a problem that is worthwhile generalizing
  • Always reasses your internal code, and continually compare it against what is available in the field.
  • Perhaps you can replace your internal encryption library with something that is industry wide. The goal should always be to minimize the amount of code in internal libraries to that which truly gives a strategic or tactical advantage, leveraging the talents (and agility) of the industry to the greatest extent possible.

In the end there are some wonderful examples of brilliant code reuse out there, but there are also a lot of terrible, horrific, productivity destroying monstrosities. How many projects have been led awry when the first task, before the product is even understand or any sort of requirements gathered, is the ever nebulous “build a framework” task…