Sunday, December 07, 2008

NIH Syndrome or Blowing Reuse Out of Proportion?

I see a lot of developers nowadays favoring re-inventing the wheel over reusing an external library or component, especially in the Ruby and Javascript communities.

The first thing that pops in my mind when I see them doing that is NIH (Not Invented Here syndrome.)

From my experience, reuse is not just about getting the features I need. It is also about stability, performance, usability, and other non-functional requirements that have been ironed out by the people who have created the reusable component and the communities that consumed it. Unless it fails in most of these areas, I usually don't see the point of re-inventing the wheel. While it seems simple to do on the surface, it is those hidden edge cases and bugs that creep up now and then that get me when re-writing it. This happens in the code when I have not thought of every possible scenario and in the design when I have not exercised the component in a real-world setting.

What's the flip-side to this argument though?

A lot of people in the agile community place great importance on minimalism. An ideal minimalistic code base does no more than necessary by your application. So, if you end up reusing components that do a lot more than needed, the complexity of learning how to configure them for your needs ends up offsetting the productivity gains behind using the components. In that case, re-inventing a smaller simpler wheel becomes a viable option.

The key thing though is determining whether a required feature is complex enough that figuring out all its edge cases and usage scenarios would be worth the time to re-write from scratch vs simply reusing an existing component that gets the job done. That trade-off is the key determining factor.

Does the programming language used play any role in the matter? I'd say yes. For example, I rarely find this option of "re-inventing the wheel" viable in Java since writing components in it is very slow. On the other hand, dynamic languages like Ruby and Javascript make it so quick and easy to build a component from scratch (when writing tests first) that it often is easier to re-write smaller components than to figure out how to use 3rd party ones.

What is your opinion of the matter? Do you have examples where you reused a component vs other examples where you ended up writing your own?


Soleone said...

Totally agree with you.

With Ruby I learned to strive for minimalism, maintainability and full control, so I rather develop small functionality myself, rather than use existing libraries.

Whereas in Java I mostly look for existing functionality somewhere, because writing something yourself takes considerably more effort with static typing and all the long method names and stuff :)

Unknown said...

Yes ..I agree too . But, abstractions are designed to solve more generic class of problems and are usually designed to solve 50 other problems along with your 1 specific problem.
For example .. weight ( and size) of a JavaScript library might not be worth it if you are using it for few very simple which case one might be better off handrolling your library ( until you hit that point of diminishing returns ).
I guess in short "it depends" ;)

Ed Merks said...

Andy, while inventing the simpler smaller wheel might well make sense if you're developing a simple small application that will always stay that way, but looking at Eclipse, it's become clear that avoiding bloat, i.e., focusing on a simple small solution, can actually cause bloat, i.e., when dozens of different simple small solutions to the same problem are all combined to yield an end result that's neither simple nor small.

Andy Maleh said...

Thanks for your comments.

Ed, could you give me a concrete example in the Eclipse platform where dozens of different simple small solutions to the same problem yielded an end result that's neither simple nor small? I'm curious if you're referring to Eclipse in general or just some projects within it.

Ed Merks said...

An example that came to light recently is the large number of SWTUtil copies that are floating around in various projects. Another example, perhaps not as direct,is the number of different ways of implementing commands/actions (which is actually more of a moving design target problem). Of course I look at many things in Eclipse and see models that are implemented in specialized ways, e.g., preferences. It also seems to me that things like IConfigurationElement exist only to avoid a dependency on DOM, yet of course most applications depend on DOM in the end anyway.

In the end, I'm not sure it's primarily so much a matter of NIH but a sense of complete control and total understanding that drives many people in this direction. It's much the same as people who would rather write 100,000 lines of code by hand than let a generator do it for them because that way they understand the code. Of course when you get 100 such people and they write 10,000,000 lines of code no one understands it all and there might not even be good common underlying patterns to help produce the kind of regularity that would make total understanding possible.