7. Tips for interface design
Writing a good library interface takes a lot of practice and thorough
understanding of the problem that the library is intended to solve.
If you design a good interface, it won't have to change often, you won't
have to keep updating documentation, and users won't have to keep
relearning how to use the library.
Here is a brief list of tips for library interface design, which may
help you in your exploits:
- Plan ahead
- Try to make every interface truly minimal, so that you won't need to
delete entry points very often.
- Avoid interface changes
Some people love redesigning and changing entry points just for the heck
of it (note: renaming a function is considered changing an entry
point). Don't be one of those people. If you must redesign an
interface, then try to leave compatibility functions behind so that
users don't need to rewrite their existing code.
- Use opaque data types
The fewer data type definitions a library user has access to, the
better. If possible, design your functions to accept a generic pointer
(which you can cast to an internal data type), and provide access
functions rather than allowing the library user to directly manipulate
That way, you have the freedom to change the data structures without
changing the interface.
This is essentially the same thing as using abstract data types and
inheritance in an object-oriented system.
- Use header files
If you are careful to document each of your library's global functions
and variables in header files, and include them in your library source
files, then the compiler will let you know if you make any interface
changes by accident (see section 7.1 Writing C header files).
- Use the
static keyword (or equivalent) whenever possible
The fewer global functions your library has, the more flexibility you'll
have in changing them. Static functions and variables may change forms
as often as you like... your users cannot access them, so they
aren't interface changes.