Ada 95 Quality and Style Guide Chapter 8

Chapter 8: Reusability - TOC - 8.3 ADAPTABILITY

8.3.8 Implementing Mixins

guideline

  • Consider using abstract tagged types and generics to define reusable units of functionality that can be "mixed into" core abstractions (also known as mixins).

  • example

    Note the use of an abstract tagged type as a generic formal parameter and as the exported extended type in the pattern that follows, excerpted from the Rationale (1995, §4.6.2):

    generic
       type S is abstract tagged private;
    package P is
       type T is abstract new S with private;
       -- operations on T
    private
       type T is abstract new S with
          record
             -- additional components
          end record;
    end P;
    

    The following code shows how the generic might be instantiated to "mixin" the desired features in the final type extension. See also Guideline 9.5.1 for a related example of code.

    -- Assume that packages P1, P2, P3, and P4 are generic packages which take a tagged
    -- type as generic formal type parameter and which export a tagged type T
    package Q is
       type My_T is new Basic_T with private;
       ... -- exported operations
    private
       package Feature_1 is new P1 (Basic_T);
       package Feature_2 is new P2 (Feature_1.T);
       package Feature 3 is new P3 (Feature_2.T);
       package Feature_4 is new P4 (Feature_3.T);
       -- etc.
       type My_T is new Feature_4.T with null record;
    end Q;
    

    rationale

    The Rationale (1995, §4.6.2) discusses the use of a generic template to define the properties to be mixed in to your abstraction:

    The generic template defines the mixin. The type supplied as generic actual parameter determines the parent . . . the body provides the operations and the specification exports the extended type.

    If you have defined a series of generic mixin packages, you would then serialize the instantiations. The actual parameter to the next instantiation is the exported tagged type from the previous instantiation. This is shown in the second code segment in the example. Each extension is derived from a previous extension, so you have a linearized succession of overriding subprograms. Because they are linearized, you have a derivation order you can use to resolve any conflicts.

    You should encapsulate one extension (and related operations) per generic package. This provides a better separation of concerns and more maintainable, reusable components.

    See Guideline 9.5.1 for a full discussion of the use of mixins.


    < Previous Page Search Contents Index Next Page >
    1 2 3 4 5 6 7 8 9 10 11
    TOC TOC TOC TOC TOC TOC TOC TOC TOC TOC TOC
    Appendix References Bibliography