Reuse Implies Coupling
Most of the Big Topics (with a capital b and t) in the discussion about software engineering and practices are about improving productivity, and avoiding mistakes. Reuse has the potential to address both dimensions. It can improve your productivity since you needn't write that code yourself that you reuse from elsewhere. And after code has been employed (reused) many times, it can safety be considered tested and proven more than your average piece of code.
No surprise that reuse, and all the debate on how to achieve it, is around for decades. Object oriented programming was about reuse, component ware, parts of open source development, and model driven architecture with all possibilities for variation. At the same time, software reuse has hardly lived up to its promises.
There are many items that we just reuse, and have reused for decades without much thought: operating systems, libraries, middleware. And we have enjoyed some components from the open source projects. So, did we create our own software, reusable among our own projects? We did, but with limited success. Here is some of the reason:
- reuse requires a first user. Attempts to create a library for common use, without having a real need in some real project that spends real time and money, remaing pointless.
- reuse requires a second user. Once used, most of the code is not reused in a different project.
Resaons against reuse:
- not invented here
- crappy quality: interfaces
- crappy quality: dependencies
- crappy quality: performance (in the 2nd users scenarios)
Even if you have overcoem all this, and started to develop reusable components in-house. You will find that sooner or later you have three different parties. (1) the creators and maintainers of the reused component; (2) the projects that already use the component; (3) the projects that are about to reuse that component.
The different groups have strongly opposing desires. Completed projects strive to avoid any changes to the once published component, since each change introduces some risk and some work. Starting projects strive to adapt the component also to their needs, i.e. they long for changes. Unless you have reached a very stable state (see ->library), you will have some debate here. Not just about interfaces and technology. You'll be surprised to find that now different projects are influencing the same code base, and people, and their schedules suddenly are coupled since some action for one of them causes work in the other one.
Do not make your code depend on some file that is intended to change as the project progresses.
It is very convenient to have a global file that lists all error codes in the system. When starting the new component, you proudly add a handful: look, I am a part of this! Only to find your colleagues moan about the extra build time. How dare you change this file?
Couldn't you just do what everybody does:
- reuse some error codes that are already in there.
- when existing codes don't match the intended meaning, document their specific meaning in your component documentation.
error.h file was intended to provide a great place to look for the meaning of codes. At the same time, it is a central component that is intended to change as the project proceeds. So it is your base, but it is quicksand.
How to get out? Consider this:
- real generic error messages (in the style of STL exceptions)
- a distinct
error.hfile per component