In the years which have passed since we first made these recommendations to Borland, what we intended to accomplish by this suggestion has become a principal design feature of C#. In C# however (and now in other Microsoft .NET tools), defined member properties are simply eliminated in a descendant by writing designers and overriding a PreFilterProperties( ) designer method. If this results in CIL (Compiled Intermediate Language) instructions which simply leave out undesirable members, and if designers are never ported into end product, alright — this delivers our objective in a relatively efficient fashion. Otherwise, the following class design prescription is an obligation, deviation from which can only obstruct proper descendant class library design. Tools not built to these standards do not mean only that the best further product cannot be built with them — tools/libraries failing to meet this standard *often* mean that only very undesirable product can be derived from them.

A primary goal of class library design should be to account for all downstream design needs. A principal problem engendered by present ad hoc class library designs however, is that class trees provide no opportunity to efficiently avoid exposing members which are adverse to the purposes of derived classes.

Any potentially detrimental exposure in any class which must be used as a base class is *very* bad design, because adverse exposure is easily avoided not by further work, but by simply dividing the code of each usual ad hoc class into a separate root class which does not expose members, and a further consumer class, derived from the root class, which does expose consumer members.

Adherence to this vital principle means root classes wholly embody a less exposed form of each consumer class, with derived consumer classes simply exposing usual consumer members as predicated by the purpose of the consumer class. Downstream classes therefore can derive from the root trunk to expose any desirable subset of the members which ad hoc class library designs presently expose altogether, in a single, incontrovertible consumer class.

Simply by organization, the exposure problems of ad hoc class libraries are eliminated:

    • ClassName__R root classes embody unexposed members and the underlying functionality of classes at private and protected levels.
      • The class is effectively written in the root class.
      • Further root classes descend from each other to form a principal root trunk.
    • Usual end user classes (EUC) simply promote necessary exposure.
    • Downstream classes can descend from the root trunk to provide any desirable subset of exposure, merely by promotion.
      • Good descendant designs are always achievable, because class nodes exist which impose no undesirable exposure.
    • Or, where design requisites permit, downstream classes can simply descend from the usual consumer branch.
      • Because this is the only option of ad hoc class library designs, there is often no way to avoid undesirable exposure.

Exposure flaws introduced by adverse, ad hoc class lineage are irreversible for library consumers, and even for VCL designers.


The TTabSheets of TPageControl for instance unnecessarily publish Top, Left, Height, and Width properties which should not be operated on (but can be operated on), and which wage war against an unpublished Align property. Even if the unexposed Align property happens to prevail, no engineering or end user issue would exist if Top, Left, Height, and Width were private, as predicated by our Root+EUC branching prescription.

Similarly, if we want to build a simple visual component which regulates its own height and cannot expose its Height property or be aligned alLeft, alRight, or alClient, then we can only build this component by insulating it as a private subcomponent and integrating a substantial redundant interface, just to hide the unnecessarily exposed members. The proper encapsulation of these properties (mere non-exposure) is impossible, merely because VCL authors have made it impossible.


Similar problems are engendered by inflexible method declarations. Rather than letting ad hoc intentions largely prescribe declarations serving the immediate class and a narrower, any method which may eventually need to be revised in any way must be declared abstract, virtual, or dynamic.

  • Because we cannot override constant methods, we can only write alternate methods which carry the baggage and possible dangers of the unwanted method with the new.
    • Redundant resources are along for the ride.
    • Developers can still run the undesirable method.
      • Our very need to override the method means it always does what we do not want it to do.
      • But the only thing to prevent anyone from calling it is documentation.

Neither is a promise of flexibility difficult to deliver, because we can do this simply by spinning off a separate branch of ClassName__RO classes (overridable), liberally declaring abstract, dynamic, or virtual methods.

© Copyright 1995-2007, by ADVANCE Information Systems, Inc. ALL RIGHTS RESERVED.Copyright 1995-2007, by ADVANCE Information Systems, Inc. ALL RIGHTS RESERVED.

Firefox™.Best viewed in Mozilla Firefox™.