Essential Design Idioms for Packages

Motivation

Packages, especially library packages, are modules, and as such they are the fundamental building blocks of Ada programs. There is no language-prescribed way to use packages when designing an application, the language just specifies what is legal. However, some legal approaches are more advisable than others.

In particular, packages should exhibit high cohesion and loose coupling [1]. Cohesion is the degree to which the declarations within a module are related to one another, in terms of the problem being solved. In short, unrelated entities should not be declared in the same module so that the reader can focus on one primary concept. Coupling is the degree to which a module depends upon other modules. Loose coupling enhances comprehension and maintenance because it allows the developer/reader to examine and modify the module in relative isolation. Coupling and cohesion are interrelated, in that higher cohesion tends to result in less coupling.

Solution

Three idioms for packages were envisioned when the language was first designed. They were introduced and described in detail by the Rationale document for the initial language design [2]. They were then further developed in Grady Booch's book Software Engineering with Ada [3], a foundational work on design with the (sequential part of the) language. Booch added a fourth idiom, the Abstract Data Machine, to the three described by the Rationale.

These four idioms have proven themselves capable of producing packages that exhibit high cohesion and loose coupling, resulting in more comprehensible and more maintainable source code.

These idioms pre-date later package facilities, such as private packages and hierarchical packages. Idioms for those packages will be described separately.

Although generic packages are not actually packages, their instantiations are packages so these design idioms apply to generic packages as well.

Because these are idioms for modules, they are differentiated by what the package declarations can contain. But as you will see, what they can contain is a reflection of the degree of information hiding applied.

Essential Idiom 1: Named Collection of Declarations

In the first idiom the package declaration can contain other declarations only for the following:

  • Objects (constants and variables)

  • Types

  • Exceptions

The idea is to factor out the common content required by multiple clients. Declaring common content in one place and letting clients reference the one unit makes the most sense.

For example, the following package declares several physical constants used in a high-fidelity aircraft simulator. These constants are utilized throughout the simulator code, so they are declared in one place and then referenced as needed:

package Physical_Constants is
   Polar_Radius   : constant  := 20_856_010.51; --  feet
   Equatorial_Radius : constant  := 20_926_469.20; --  feet
   Earth_Diameter : constant  :=
     2.0 * ((Polar_Radius + Equatorial_Radius)/2.0);
   Gravity  : constant  := 32.1740_4855_6430_4; --  feet/second**2
   Sea_Level_Air_Density   : constant  := 0.002378; --  slugs/foot**3
   Altitude_Of_Tropopause  : constant  := 36089.0; --  feet
   Tropopause_Temperature  : constant  := -56.5; --  degrees-C
end Physical_Constants;

No information hiding is applied with this idiom.

Pros

Packages designed with this idiom will have high cohesion and low coupling.

The idiom also enhances maintainability because changes to the values, if necessary, need only be made in one place.

Cons

When a library package contains variable declarations, these variables comprise global data. In this sense global means potential visibility to multiple clients. Global data should be avoided by default, because the effects of changes are potentially pervasive, throughout the entire set of clients that have visibility to it. In effect the developer must understand everything before changing anything. The introduction of new bugs is a common result. But if, for some compelling reason, the design really called for global data, this idiom provides the way to declare it.

Notes

  1. The rules for what these idiomatic packages contain are not meant to be iron-clad; hybrids are possible but should be considered initially suspect and reviewed accordingly.

Bibliography