I propose a four-tiered nomenclature for shared code:
Code which can in principle be delivered as a library and which stands completely alone. All parties agree on the interface and functionality. This is best in situations when there is little or no disagreement about functionality, for example: a vector class.
Level 1 code is fully contained – it does not provide interfaces which are expected to be overloaded (as opposed to level 2).
Although level 1 code may in principle be delivered as a library, there may be good reasons such as portability to deliver it as source code. However, when delivered as source code the recipient should understand that because it is declared as level 1, it should be considered read-only source.
A skeletal system which is intended to have custom functionality added. For example, a windowing toolkit. The framework expects that the user is going to "hook-in" or overload functionality. The level 2 code consists of a lot of level 1 code with interfaces and documentation which explain the expected behavior of the higher level code. For example: "the handleEvent() call will be issued when an event is ready. The overloaded implementation is expected to call the ancestor implementation and not block." Or, "this function pointer will be called by the code just before it displays in order for the higher level code to modify the position."
A system which is complex enough to warrant sharing code, but which will need to be modified by the recipient for their needs.
For example, consider a 3D mesh data structure. It may contain very useful functionality such as a sorter, hierarchical transformations, import/exporter, etc. But it is also likely to be dependent on low level structures such as face and vertex which could be radically different in the recipient’s architecture. Thus, in order for it to be useful to the recipient’s team, the recipient must be able to tweak the low level details and this can only be done efficiently by modifying the source code.
Level 3 code is a used to bootstrap a team. It helps the recipient create a system without having to start from scratch, but this process is not repeatable; once the recipient starts to modify the code, they can not replace it with a new version of the code. This is the main difference between level 2 & 3.
Level 3 code is warranted over level 2 when the overhead of a framework is too cumbersome or too inefficient. CAUTION: It is often tempting for a programmer to create level 3 code when a level 2 code is possible but would be more work to architect. Programmers should look out for opportunities to create level 2 code instead of level 3. For example, the 3D mesh system described above may be convertible to level 2 by simply isolating the face and vertex retrieval into an interface instead of making hard-coded assumptions about the data structures.
Algorithms and data structures which are complex enough to warrant descriptive essays. For example, many 3D terrain systems are very similar or have extremely similar sub-components but are almost never sharable because of custom optimizations. It is not practical to believe that a level 2 terrain system will be state-of-the art. Similarly, level 3 code will probably end up being modified beyond recognition and thus not serve any real purpose other than by example. Thus, a terrain system falls into the category of a pattern: algorithms and vocabulary are shareable, but not much else.
Level 4 patterns may also describe systems which are extremely simple yet so amorphous that they do not warrant source code. Excellent examples of such patterns can be found in the book: Design Patterns: Elements of Reusable Object-Oriented Software by Gamma, Helm, Johnson, Vlissides.
A system may consist of components from different levels. For example, an assert system may have level 1 utility functions (e.g. stack trace, fancy dialog box) but also have level 3 code. See White Paper #4 (improving Inmformation Gained From Fatal Exceptions for an example system which has this structure.
Will McBurnett, Pete Shellus, Steve Beeman