Open source is a fantastic thing in the world of software. It allows you to quickly expand, grow, and learn from the hard work of others. And, I mean, the best way to improve the wheel is to start with one and not rebuild it from the ground up first. However, it does not seem many people always like to talk about the dark-side of code reuse. While Joel has a defense on Not-Invented-Here-Syndrome (of which I largely agree with), I think it runs much deeper than this.
Adopting someone elses code is much like adopting their 17 year-old child; at first it may seem harmless (though, admittedly, somewhat uncomfortable). Aside from feeding it (i.e. giving it the right inputs), it seems to behave nicely (most code does too¦ for the common cases). After a while, though, its history begins to come out. As you want to help that child grow and prepare him- or herself for life, you are now stuck with all of the bad parenting decisions that occurred before you were in the picture.
More explicitly, a mature piece of code is generally fantastic to work with for your general cases, but often times you are left with certain design decisions which may occasionally limit your use case or require you to make adjustments to your own design. If you come to such an impasse while developing, you do one of a few things:
- Incur tech debt. You can scrap a portion of your design (i.e. take a short-cut) and conform to the way that the open-source project requires while trying to keep the rest of your design exactly the same. In general, this is not a very good solution (unless you had a truly sub-optimal design). In particular, when you start shoehorning your current design to fit something else, you will generally make poor decisions declaring, this is a temporary hack which doesnt become so temporary in the end. That being said, modularity is typically key in good software, so this design may be limited to single component instead of an entire system.
- Redesign your system. You can redesign your whole system around this new piece of software and its idiosyncrasies. This is generally incredibly costly if youve already built out a large part of your system, but may not always be totally infeasible. If the library provides you with some service you cannot write yourself or it really does not make sense for you to in-house this process, then this may be an effective decision to make.
- Fix the library. Assuming you have the know-how, you can simply update the open-source library to behave as you need. That being said, if you dont already have someone familiar with the librarys internals, this could quickly turn into a costly problem. Not to mention, the poor dev you send down that rabbit hole may never emerge the same. So while this is and can be a feasible solution, you have to remember that youre now taking on a support role for a potentially behemoth project.
- Roll your own. Finally, you can simply scrap all of the work youve done integrating this library into your project and rewrite your own solution (and then integrate that new software). This is not always an incredibly daunting task and can often be the best solution. However, you clearly need to consider how much time you have already invested in the open source project and whether or not it is better at this point to spend the amount of time and effort required to create, support, and maintain this new product. Preferably, however, you would actually consider these options before you build. In that case, you would still want to consider and project these costs.
As you can see, when you incorporate someone elses
monster baby into your project, you inherit a lot from them. If their software doesnt work how you need or doesnt work as you expect it to, you run into a plethora of problems. To avoid these issues, the first and most important step is to design your system that you want to build. You should be able to put as many ideas about your system down on paper before ever writing a single line of code. Once you have done this, you can look through and evaluate the open source world for feasible solutions. By having a design document and set of requirements for your system, you can actually tell whether or not your required set of supported features are encapsulated within an open source package. Likewise, you can determine whether the cost of building into that package and supporting it (for missing features) is more worth your time than rolling your own solution. After all, someone else basically solved the problem youre looking to solve why ignore it altogether. Remember that there is a cost to everything you put effort into.