|Ada 95 Quality and Style Guide||Chapter 4|
4.1.6 Child Library Units
If a new library unit represents a logical extension to the original abstraction, define it as a child library unit.
If a new library unit is independent (e.g., introduces a new abstraction that depends only in part on the existing one), then encapsulate the new abstraction in a separate library unit.
Use child packages to implement a subsystem.
Use public child units for those parts of a subsystem that should be visible to clients of the subsystem.
Use private child units for those parts of a subsystem that should not be visible to clients of the subsystem.
Use private child units for local declarations used only in implementing the package specification.
Use child packages to implement constructors, even when they return access values.
The following example of a windowing system is taken from Cohen et al. (1993) and illustrates some of the uses of child units in designing subsystems. The parent (root) package declares the types, subtypes, and constants that its clients and subsystems need. Individual child packages provide specific parts of the windowing abstraction, such as atoms, fonts, graphic output, cursors, and keyboard information:package X_Windows is ... private ... end X_Windows; package X_Windows.Atoms is type Atom is private; ... private ... end X_Windows.Atoms; package X_Windows.Fonts is type Font is private; ... private ... end X_Windows.Fonts; package X_Windows.Graphic_Output is type Graphic_Context is private; type Image is private; ... private ... end X_Windows.Graphic_Output; package X_Windows.Cursors is ... end X_Windows.Cursors; package X_Windows.Keyboard is ... end X_Windows.Keyboard;
The user can create more precise packages with less cluttered interfaces, using child library packages to extend the interfaces as needed. The parent contains only the relevant functionality. The parent provides a general-purpose interface, while the child units provide more complete programming interfaces, tailored to that aspect of an abstraction that they are extending or defining.
Child packages build on the modular strength of Ada where "the distinct specification and body decouple the user interface to a package (the specification) from its implementation (the body)" (Rationale 1995, §II.7). Child packages provide the added capability of being able to extend a parent package without recompiling the parent or the parent's clients.
Child packages allow you to write logically distinct packages that share a private type. The visibility rules give the private part of the child specification and the body of the child visibility into the private part of the parent. Thus, you can avoid creating a monolithic package for the sake of developing abstractions that share a private type and need to know its representation. The private representation is not available to clients of the package, so the abstraction in the package and its children is maintained.
Using private child packages for local declarations enables you to have available the support declarations you need when implementing both the parent package and extensions to the parent package. You enhance the maintainability of your program by using a common set of support declarations (data representations, data manipulation subprograms). You can modify the internal representation and the implementation of the support subprograms without modifying or recompiling the rest of your subsystem because these support subprograms are implemented in the body of the private child package. See also Guidelines 4.1.1, 4.2.1, 8.4.1, and 8.4.8.
See also Guideline 9.4.1 for a discussion of the use of child library units in creating a tagged type hierarchy.
|< Previous Page||Search||Contents||Index||Next Page >|