[ Team LiB ] Previous Section Next Section

Gotcha #94: Failure to Employ Degenerate Hierarchies

The design heuristics for base classes and standalone classes are very different, and client code treats base classes very differently from standalone classes. It's therefore advisable to decide what kind of class you're trying to design before you design it.

Recognizing early in development that a class will become a base class in the future and transforming it into a simple, two-class hierarchy is an example of "designing for the future," in that it forces users of the hierarchy to write to an abstract interface and eases future augmentation of the hierarchy. The alternative of initially employing a concrete class and introducing derived types later would force us, or our users, to rewrite existing framework code. Such simple hierarchies may be termed "degenerate hierarchies" (which, no matter what one may hope, is a mathematical, not moral, use of the term "degenerate").

Standalone classes that later become base classes wreak havoc on using code. Standalone classes are often implemented with "value semantics"; that is, they're designed to be efficiently copied by value, and users are encouraged to pass such arguments by value, return them by value, and assign one such object to another.

When such a class later becomes a base class, every such copy becomes a potential slice (see Gotcha #30). Standalone classes may also encourage the declaration of arrays of class objects; this can later lead to errors in address arithmetic (see Gotcha #89). More obscure errors may also arise when generic code is written with the assumption that a particular type of object has a fixed size or fixed set of behaviors. Start a potential base class off as an abstract base class.

Conversely, many or perhaps most classes will never be base classes and should not be factored this way. Certainly, small types that must be maximally efficient should never be factored this way. Common examples of types that should rarely be part of a hierarchy are abstract numeric types, date types, strings, and the like. As designers, it's up to us to use our experience, judgment, and powers of clairvoyance to apply this advice appropriately.

    [ Team LiB ] Previous Section Next Section