views:

360

answers:

12

It's pretty cliche that reinventing the wheel is evil. Of course, if there's a good canned solution, I agree. The question, though, is how far to you go to avoid reinventing the wheel when there is no optimal existing wheel? Here are some cases:

  1. The existing wheel is in a different language than you're using or want to use. You'd have to switch languages or write a bunch of crufty glue code to use it.
  2. The existing wheel only does approximately what you want and you'd have to resort to some kludgery to make it do exactly what you want. For example, maybe the existing wheel is a standalone program and you need a library. You might be able to fake it using a bunch of shell() commands, but that's a massive kludge. Another example is if the existing wheel is something mathematical and only does exactly what you want after you apply a bunch of transformations to the input that may be unnecessarily slow or lose precision.
  3. You just plain hate the API or UI of the existing wheel at a subjective level.
  4. The existing wheel is a huge library that is designed like a Swiss army knife, is very complex to use, and adds a massive dependency to your codebase, when all you need is a tiny subset of the functionality.
  5. The existing wheel is implemented in poorly documented spaghetti code, and you'd practically have to reverse engineer it if you ever needed to make even the slightest modification, or possibly even to figure out how to use it.
A: 

For 1 and 2, I would usually go ahead and reuse the wheel because sometimes their solution is the quickest solution I can find. Besides, learning a little bit about a plausible solution will allow me develop an even more efficient solution.

For 3 to 5, I would reinvent the wheel because it means that my issue is somewhat unique, and I need the best way to make it work for my problem. Also, if their wheel is too hard to understand, it just make sense timewise to just create my own solution.

johnofcross
+2  A: 

In my experience, trying to avoid reinventing the wheel most of the time lead to dissapointment. Eventually, I ran into problems I could not solve using the existing implementation I had chosen to use.

Now, I try to evaluate what it is exactly I want to achieve, which is always a good thing to do anyway. Doing so hardly points to an existing technique anymore. That's not to say it can't happen at all. When developing a website with some interacting elements, an existing javascript library is absolutely the way to go.

Kriem
A: 
  1. The existing wheel is in a different language than you're using or want to use...
  2. The existing wheel only does approximately what you want and you'd have to resort to some kludgery...
  3. You just plain hate the API or UI of the existing wheel at a subjective level...
  4. The existing wheel is a huge library that is designed like a Swiss army knife, is very complex to use...
  5. The existing wheel is implemented in poorly documented spaghetti code...

In all 5 of these I would rebuild the wheel. Unless it's for something at the job, in which case the decision is up to my boss. But he'd probably agree with me except maybe in situation 3.

Kris
come on... it must depend on how big this wheel is, right?
nickf
well, yeah absolutely.
Kris
+1  A: 

If you are looking to use a canned solution or application, there are 2 very different ways of looking at it.

A. How can we change the canned solution to better fit us.
B. How can we change to better fit with the canned solution.

Option A will lead to problems and headaches. In the long run, option A will cost more money and time than just doing it your self.

Option B will be faster, cost less and will bring happiness and peace. Well I don't know about the happiness and peace but you get the point.

If you can't do option B, than you are more then likely better off to code it yourself.

Tony
+2  A: 

Very simply:

As far as it is cheaper to reinvent instead of buy-in.

The price includes development, training, maintaining, risks. And of course, this is hard to judge, but it's the only thing that matters.

Stefan Steinegger
A: 

I'll take one by one. I see no generic answer, however... :)

1 The existing wheel is in a different language than you're using or want to use. You'd have to switch languages or write a bunch of crufty glue code to use it.

I would think what I win, what I loose, in terms of effort of implementation (both solutions), and effort for maintaining/extending/scaling the solution. Other "non-functional" factors may apply.

2 The existing wheel only does approximately what you want and you'd have to resort to some kludgery to make it do exactly what you want.

Same answer as for the first question. I can't think of a generic answer.

3 You just plain hate the API or UI of the existing wheel at a subjective level.

Being subjective when choosing a technology is not the best thing to do... I try to avoid, even if I provoke some pain (specially to my own person).

4 The existing wheel is a huge library that is designed like a Swiss army knife, is very complex to use, and adds a massive dependency to your codebase, when all you need is a tiny subset of the functionality.

If I have access to the code source and I can isolate what I need, lucky me. Again, answer 1 applies as well.

5 The existing wheel is implemented in poorly documented spaghetti code, and you'd practically have to reverse engineer it if you ever needed to make even the slightest modification, or possibly even to figure out how to use it.

If I have no choice but to use it, I try to document it on touch, to refactor it when identifying big problems... And to evaluate the costs of doing this and the risks of having problems handling and changing poorly written code...

Cătălin Pitiș
+1  A: 

I would not much like the wheel described by your numbered scenarios. If a proposed solution will actually add cruft or maintenance headaches in the future and will take time to learn and implement, what are you actually gaining by using it?

I agree that the wheel should not be re-invented whenever possible, but under these circumstances, I would devote some time to finding a better wheel.

tehblanx
A: 

Go ahead and (try to) reinvent it. I just implemented a parser using straight recursive descent using only string.find in Python. I could have used any number of existing wheels, but it would have meant adding a dependency and I would have had to (re)learn how to use the wheel. As it was I think my parser is not much more complicated than the code I'd need to use a library, and it produces more usable error messages.

reinvented wheel: parseQuery.py documented here.

When you find that the wheel was harder to reinvent than you thought maybe you can go looking around for an existing one (and have better insight into what you are looking for).

Aaron Watters
A: 

I just want to say that 4 is the one that bothers me the most. When you make a tool, just make it do one thing. Don't let the feature creep win. When adding a new feature, you should strongly consider making it a separate tool.

I also want to say that there are a lot of unmaintained wheels out there. Let's say I find some Python module that I want to include in a project. There's a stable version and a development version. The community supporting the module is all over the development version. They're all using it, and ignoring the very old stable version. As a result, the development version is the actually useful module, and the stable is useless. However, I'm not looking to join their community and track their development. I need a stable "wheel" that I can just use and forget. When projects are in that state of flux, it creates a barrier to entry. Projects need to make the stable version a priority such that their wheel can actually be used by others reliably.

Apreche
+1  A: 

When I find a feature of some Java library (Java VM, IBM MQSeries, Spring, Hibernate, you name it) that I don't like, I get the source and fix it. When I think there is a chance this fix will be included, I'll hand it back (after talking to my boss, etc).

The point is: I'm not afraid at all to disassemble an existing library and patch it. I've hammered IBM MQSeries into giving readable error messages (MQRC_NO_MESSAGE_AVAILABLE instead of "2035"), I've made the DB2 database driver reloadable, I fixed deadlock issues in ActiveMQ and I did patch rt.jar once or twice.

People will complain "but what when a new version comes out?" Well, most projects never upgrade. They live for two-three years and they are dead before upgrading becomes a real issue. Next, my patches are projects in the CVS. They contain the original source, the patches, test cases, everything. When a new version does come out and we really need it, it takes only a few moments to figure out whether there is a problem or not. Most often, there isn't because this part hasn't changed. Sometimes, the bug is fixed, which is just as well. Or there is a new feature or workaround which solves the issue in a different way. So far, I was never stuck.

Aaron Digulla
A: 

I ran into a case where the wheel was under a given licensing scheme, and suddenly changed for another one that was certainly not suitable for my product. To make a long story short, take into account the possible evolution of your wheel and your product in the future. This is definitely part of the "risk" mentioned by others.

The best wheels are the ones you can barely trust forever: boost, QT, OpenGL ...

Jem
A: 

Now and then I reinvent the wheel on my free time just because I want to. I often find that the tool- and framework-developers get all the good bits, and what is left over for me is just libraries and glue. Sometimes that is no fun.

Edit: oh, yes, the question was how far I would go to avoid reinventing the wheel. When I am getting paid I weigh the cost of reuse against the cost of reinvention and do the one that is cheaper for the customer.

FeatureCreep