Building a library I - Rationale
What goes into building a library? It’s a good question, and one that requires stepping back a couple of steps to get a wider perspective.
The first thing
to note is that as programmers, we always find things that we do repeatedly over and over again. Putting all of these things into one place is a good move, and is expressed in the principle DRY (Don’t Repeat Yourself). Violating DRY means your code is now more brittle. Brittle here means that since your logic is repeated in more than one place, an update to the logic has to happen in multiple places. This is easily forgotten, especially as the number of places in the code base increases. This is a first indicator of a candidate for a library.
The second thing
to note, is that some things are very specific to a project. If the code will only ever be used by one particular project, it is overkill to make it into its own library. In reverse, if it is something you find yourself doing over and over again in various projects, it’s another indicator of a candidate for a library.
The third thing
to note, is that a piece of code that is logically cohesive inside the code base and is really hard to reason about, might be a good candidate for a library. Lifting it out as its own project, to be consumed by the original project as a library, could give benefits such as ease of development, more rigorous test suite, faster development and disentanglement from a mudball of code in the original project. An added benefit could be that it is now usable by other projects as well.
The fourth thing
to note, is that a library is easier to document, but also requires documentation. Documentation means work, lots of it.
The fifth thing
to note, is that a library requires support. Depending on how well defined the scope of the library is, and how popular the library becomes, the support can either be minuscule or massive.
The sixth thing
to note, is that a library, while birthed from one particular need, can expand in scope and cover many needs. This is both a blessing and a curse, as too much expansion will yield an unfocused library.
The seventh thing
to note, is that a library should be heavily focused on a particular domain. If it is not, you are writing a framework, which is a completely different ball game.
The eight thing
to note, is that a good library, is one which can be treated as a black box. The less a code base needs to know about the inner workings of a library, the better. If the code consuming the library has no need to know of the inner workings of the library, it is a piece of cake to swap out implementations under the hood, with the consuming code none the wiser. The opposite, where the consuming code does need to know about the inner workings of the library, is known as leakage, and severely limits what can be done with the library in future updates without breaking code depending on your library.
The ninth thing
to note, is that sometimes there already exists libraries that does what you want. Sometimes they are well written, and you can use them as is. Other times, you find that there are small problems with them. In those instances patches to the library usually helps. And sometimes you find yourself wishing for a different way of reaching the same goal, other than said library. In such a circumstance, you have an inidicator of a candidate for a library.
Great… now what?
So, we have a couple of different things to take into consideration. This creates a sort of matrix, where you need to weigh pros and cons.
The sweet spot is a piece of functionality, that can be written as a library, can be treated as a black box, solves one domain problem really well and is small. Depending on the alternatives, you might still go for a library, as the pain of the alternatives are greater than writing an imperfect library.
Once you have an idea for a library, the next step is the planning of the library.