One consequence of the emphasis that the Unix programming style
put on modularity and well-defined APIs is a strong tendency to
factor programs into bits of glue connecting collections of
libraries, especially shared libraries (the equivalents of what are
called dynamically-linked libraries or DLLs under Windows and
other operating systems).
If you are careful and clever about design, it is often possible
to partition a program so that it consists of a
user-interface-handling main section (policy) and a collection of
service routines (mechanism) with effectively no glue at all. This
approach is especially appropriate when the program has to do a lot of
very specific manipulations of data structures like graphic images,
network-protocol packets, or control blocks for a hardware interface.
Some good general architectural advice from within the Unix tradition,
particularly applicable to the resource-management challenges of this
sort of library is collected in The Discipline and Method
Architecture for Reusable Libraries[Vo].
Under Unix, it is normal practice to make this layering
explicit, with the service routines collected in a library that is
separately documented. In such programs, the front end gets to
specialize in user-interface considerations and high-level protocol.
With a little more care in design, it may be possible to detach the
original front end and replace it with others adapted for different
purposes. Some other advantages should become evident from our case
study.
There is a flip side to this. In the Unix world, libraries which
are delivered
as libraries
should come with
exerciser programs.
|
APIs should come with programs, and vice versa. An API that you
must write C code to use, which cannot be invoked easily from the
command line, is harder to learn and use. And contrariwise, it's a
royal pain to have interfaces whose
only
open,
documented form is a program, so you cannot invoke them easily from a
C program — for example,
route(1)
in older Linuxes.
|
|
--
Henry Spencer
|
|
Besides easing the learning curve, library exercisers often make
excellent test frameworks. Experienced Unix programmers therefore see
them not just as a form of thoughtfulness to the library's users but
as an indication that the code has probably been well tested.
An important form of library layering is the
plugin, a library with a set of known entry
points that is dynamically loaded after startup time to perform a
specialized task. For plugins to work, the calling program has to be
organized largely as a documented service library that the plugin can
call back into.