Last Updated: February 25, 2016
· keboo

Making a round wheel

This is an argument which I have seen hashed and rehashed by many developers. Should you consume existing code or write everything yourself - in other words, reinvent the wheel.

Rather than rehashing the entire argument, here are the general argument points:

Rewrite code (reinvent the wheel)
* Removes external dependencies
* Forces you to know and understand the code

Consume existing code
* Less time to implement and start testing
* Takes advantage of other’s knowledge and experience

Quite often there are good reasons to rewrite functionality that already exists. Many advocates of re-writing code will make the argument that it promotes innovation and pushes technology forward. When you have written the code, it should work exactly as designed and you should know what every line of code is doing. It is good to innovate. It is good to want to create something better than the current status quo. To those that are striving for that, I applaud you.

There is, however, a flip side to the coin; an argument which the advocates of code reuse will continuously cite. This argument suggests that people who reinvent a piece of code do so in a manner that is significantly inferior (typically in the form of bugs, performance, completeness, and conformance to standards) to previously written alternatives.

“Less bugs” is left out of the lists of pros for each school of thought, because both sides will claim that their option results in fewer bugs. The advocates of rewriting code will argue that third party utilities are often not bug free; after all what code is ever 100% bug free? The advocates for consuming existing code will argue that rewritten code is more likely to have bugs.

I think people from both schools of thought are correct to a certain degree, and there can be wisdom which may be gleaned from each. Blindly adding code to your code base which was posted on blogs, stack overflow, newly created open source projects, open source projects with little to no documentation, and vendors without a proven track record is asking for problems. In these cases, you are probably better off writing your own code, or at least investing the time to really understand and fix existing code.

Before adding an additional dependency to your project consider the following:

  • Do you know how to use the code? If not, you may spend a very large chunk of time learning how to use it properly. Using someone else’s code incorrectly is just as likely to cause bugs as writing your own code. Yet you must also consider the tradeoff, the time it takes to learn a library is time that could be spent coding your own.
  • Does the code provider have a good track record? Using well established projects which have been around for a while, are well tested and documented, and have good community reviews carry very little risk. Always consider the source of the code. If the code is open source, consider using it as an example on which to base your own code.

Now to switch to the other school of thought. Reinventing functionality when superior alternatives exist is just as bad as consuming poor code. This is especially true when writing code for protocols and specifications that have a RFC. In these cases it is best to really research alternatives before considering writing your own code. Most high level languages today have a wealth of functionality built into their frameworks. Do not re-implement this functionality. If you find yourself wondering if something is already implemented; stop coding and start Googling (or binging for those die-hard Microsoft fans). In almost every case your framework’s implementation will be faster and less buggy.

Let’s use the .NET framework as a specific example. Microsoft has built a very powerful library on which to base your software; take advantage of it. The more you familiarize yourself with the wealth of the framework the less code you will find yourself needing to write. As a result, you will end with much better code.

With .NET 3.5 and above, we have the ability to add functionality to objects which we are not able to modify directly. As the name suggests, it is used to extend the functionality of an object. Too often, I find extension methods whose purpose is to not extend functionality. Consider the following examples of poor choices for extension methods:

public static int Add(this int first, int second)

This is simply re-implementing the plus operator in a much stricter context since it only accepts ints. Do not use extension methods to re-implement operators. Your new way of using an operator is not better than the one built into the language.

public static IEnumerable<T> NotNull<T>(this IEnumerable<T> enumerable)

This method would do the equivalent of Where(x => x != null), so do not wrap existing functionality just to get a different name. The development who has to maintain your code will appreciate it.

public static void ConvertAllAndEmail<T>(this IEnumerable<T> enumerable)

This method is doing way too much. The functionality it claims to provide does not seem to relate to IEnumerable<T>. Do not create extension methods on types simply because you can. Extension methods are meant to extend functionality; to make an object richer and easier to work with. Think carefully before you add an extension method to System.Object.

There are plenty of other examples, but to be brief- learn your language/framework. Use the functionality already provided to you when possible, and only when necessary create your own custom implementations. As developers we should strive to work smarter not harder.

In conclusion, before you go trying to re-invent the wheel consider these questions.

  1. Why do you need a custom implementation? If you can’t write down an answer to this question in a couple sentences, then the problem is not understood well enough to design a solution.
  2. Does it make the code more readable? Readability is typically a judgment call (and the source of many debates between developers). Typically shorter simpler code is best. Would a new developer be able to read the code and understand what it is going on?
  3. Are there solutions that have already solved the problem? Typically you are not the first developer to want something. Search your platform/framework to see if a solution has already been provided. Quality third party solutions may also be considered if your project permits. If you cannot find any existing solution, consider the possibility you are doing it wrong.

These references should not be considered scholarly works, rather merely examples of the debate between code consumption vs. re-inventing the wheel.


[1]: Reinventing the wheel vs. code reuse

[2]: The “Reinventing the Wheel” Anti-Pattern

[3]: Re-inventing the wheel – Is it bad? (Stack Overflow)

Source: http://dotnetgeek.tumblr.com/post/35326379069/making-a-round-wheel