OOD and Ada 83
ContentsThis chapter is organized as follows:
Note: Because UML and Ada use the word "package" to designate two different concepts, this document uses the phrase "UML package" for a package in the UML acceptation, and the word "package" without qualification for an Ada package.
Mapping ClassesThe following kinds of classes in the UML notation have a mapping to Ada:
Standard Classes
A class, as defined by UML, is a set of objects that share a common structure and a common behavior. This concept is best represented as an Ada package with a private type and a set of visible subprograms.
The structure of a class is a private or limited private type, implemented as a record type. The name of the type defaults to Object. Each "has" relationship, generalization relationship, and attribute becomes a field in the record. Optionally, there may be an additional access type, called Handle, that points to the class type.
Using this representation of a class in Ada, an object is simply an instance (i.e., variable declaration) of the class type and is accessed, manipulated, and controlled by the subprograms in the class package.
Class Operations
The behavior of the class is captured by the subprograms in the visible part of the package. Each operation defined in the class is mapped to either an Ada procedure or function. The formal parameter list begins with the class type, whose name defaults to this.
Usually, several standard operations are needed for every class. Constructors (default name: Create), are responsible for creation and initialization of class objects. A copy constructor adds additional logic required when copying the contents of one object to another. The destructor (default name: Free) may deallocate memory or call other destructors. Finally, an equality operation can be added when "=" does not make sense.
Export control adornments can be attached to operations. If the export control is public, the subprograms will be part of the visible part of the package. Otherwise, the subprogram will be hidden in the body.
Utilities
Generally, a utility is used to collect a set of free subprograms that are cohesive by some measure. For instance, consider a collection of subprograms (String_Compare, Upper_Case, ...) that manipulate a string, yet do not need any direct access to the structure of a string. These can be gathered together into a utility.
In Ada, a utility is represented as a package containing a collection of subprograms. These packages typically have names ending with suffixes like _Utilities, _Services, etc. A utility package has no class type.
Parameterized Classes
A parameterized class in the UML notation corresponds to a generic package in Ada. Class parameters become generic formal parameters.
Bound Classes
A bound class maps to a generic instantiation in Ada.
Mapping RelationshipsThe following relationships defined in the UML notation have a defined mapping to Ada:
- Dependency Relationships
- Has Relationships
- Generalization Relationships (Inheritance)
- Association Relationships
Dependency Relationships
The dependency relationship means that a client class is dependent on the interfaces of a supplier class. A dependency relationship maps to an Ada with clause. Note that a "has" association or generalization relationship also implies a with clause.
Export control adornments on a dependency relationship define the location of the with clause. If the relationship is public, the clause will be in the package specification. Otherwise, it will be in the body.
Has Relationships
"Has" relationships are not part of the UML notation. However, they can be created in Rose using the View > As Booch option. When viewed using the Booch or OMT notation, they are displayed as unidirectional aggregation relationships.
The "has" (aggregation) relationship denotes a whole/part association. There are two distinct types of "has" relationships: by-value and by-reference. A by-value "has" relationship, also known as physical containment, generally indicates that the part does not exist independently of the whole, and/or the whole is responsible for construction and destruction of the part. A by-reference relationship, also referred to as logical containment, indicates that the part is not physically contained within the whole and is potentially shared with other objects.
A "has" relationship becomes a component in the client's class record type. The type of the record component depends on the by-value or by-reference nature of the relationship. If the relationship is by-value, the type of the component is the class type of the part class (i.e., Object). If the relationship is by-reference, the component type must use the access type of the part class (i.e., Handle).
When the static adornment is added to a "has" relationship, the relationship is interpreted as being a class relationship rather than an object relationship. In Ada, this means that the relationship will be represented as a variable declaration in the private part of the client's package.
Generalization Relationships (Inheritance)
Ada 83 has no direct language support for inheritance. With the help of automation, however, inheritance can be achieved. There are actually several ways to support inheritance; the one chosen for the Ada 83 Generator is the best balance of understandability, extensibility, and simplicity.
Inheritance can best be achieved by using type extension, which builds on an existing class by inheriting, modifying, and/or adding to both the structure and behavior of the existing type. In Ada, type extension is accomplished by creating a new class package that re-declares all of the subprograms of the superclass, and declares a new class type that includes an instance of the superclass as a component. The implementation of the re-declared subprograms simply call back to the subprograms in the superclass' package. The subclass' package can then be extended by adding additional attributes, relationships, and operations, and/or overriding the implementation of the re-declared subprograms.
Association Relationships
Associations are similar to "has" relationships.
- For unidirectional associations, the generated code is identical to that which would be generated for a "has" relationship.
- For bidirectional associations the data structures are identical to that which would be generated for two symmetrical "has" relationships. An association provides a set of operations that preserve the integrity of the linkage between the objects.
- Association classes provide an additional mechanism to store and retrieve the information held by the association class.
Achieving Polymorphism with AdaBecause Ada 83 has no built-in polymorphism, the Ada 83 Generator produces the subprograms and data structures needed to emulate polymorphism.
This technique consists of creating a union package over the root class and its direct subclasses. This package consists of a variant record type that uses an enumeration type listing the possible variants. The enumerated type includes the root class and all subclasses. This package also re-declares all of the subprograms exported by the superclass. The body of each of these subprograms uses the discriminant of the variant record to dispatch a call to the appropriate subprogram.
Unmapped Elements for AdaThe following elements are part of the UML notation, and can be described in Rational Rose, but have no mapping to the Ada language. They are ignored or flagged by the code generator:
- Metaclasses
- Abstract classes
- Friendship
- Multiple inheritance
Rational Software Corporation
http://www.rational.com support@rational.com techpubs@rational.com Copyright © 1993-2001, Rational Software Corporation. All rights reserved. |