Tuesday, 17 June 2008

Participant Roles

Binary relationships and subtype-supertype relationships are defined between participant objects in information models. Binary relationships have two main participants and one optional associative participant. The associative participant object can't be either of the main participant objects in a binary relationship. However, the main participant objects may be the same object, i.e. when the binary relationship is a reflexive relationship (discussed in OOA96). Subtype-supertype relationships have one supertype participant and two or more subtype participants. A specific object can't participate more than once in a subtype-supertype relationship.

To identify a particular participant you need the relationship and object involved. However, you also need additional information to distinguish between the main participant objects in a reflexive relationship. The verb phrases associated with the main participants can be used to distinguish between them in a asymmetric reflexive relationship. However, verb phrases can't be used to distinguish between main participants in a symmetric reflexive relationship (introduced in OOA96). Several existing action languages use verb phrases to help identify participants in relationship navigation expressions. Obviously, this is not sufficient for symmetric reflexive relationships.

OOA08 formalizes the concept of participant role so that verb phrases don't need to be used to help identify participants. Participant roles include first, second, associative, supertype, and subtype. The first and second roles arbitrarily denote the main participants in a binary relationship. The associative role denotes an associative participant. The supertype and subtype roles denote a supertype and subtype participant respectively.

OOA08 initially defined all of these roles as literal values. However, the first and second roles can now be changed allowing short role names to be associated with the main participants of a binary relationship. In practice, participant roles are only used with reflexive relationships. In asymmetric reflexive relationships, the roles should be self evident, e.g. the roles client and server are used in the reflexive relationship between Domain objects formalized by the associative Bridge object (from OOA of OOA). In symmetric reflexive relationships, the default first and second roles should be used.

Friday, 13 June 2008

Polymorphic Events

OOA96 introduced the concept of polymorphic events into Shlaer-Mellor OOA. It allows a supertype object to define a polymorphic event which is mapped to events associated with subtype object lifecycle models. A polymorphic event is generated without the need to know which subtype object is associated with the polymorphic event's supertype object. A mapped event is either a lifecycle model transition event (known as a true event) or another polymorphic event where the subtype object is itself a supertype object in another subtype-supertype relationship. Obviously, mapped events can't be assigner model events or creation events since a supertype and subtype object instance must exist for a polymorphic event to be routed. Polymorphic events and their corresponding true events may or may not have the same meaning.

OOA08 defines a new type of event destination called a polymorphic destination for encapsulating a set of polymorphic events associated with a specific subtype-supertype relationship. It defines the label prefix for a polymorphic destination as the subtype-supertype relationship ID followed by a -P suffix, e.g. R2-P. This eliminates the need in OOA96 to use a * suffix when referencing polymorphic events since the -P suffix performs the same function. Polymorphic destinations are the only event destinations that do not appear on communication models. However, true events do appear on communication models with a prefix indicating the polymorphic event which is routed to the true event, e.g. R2-P1 → CA2: Perform task. OOA08 uses a right arrow rather than the equals specified in OOA96 since an equals suggests a bidirectional relationship which doesn't exist.

Since polymorphic events are associated with a subtype-supertype relationship rather than a supertype object in OOA08, a polymorphic event always results in one and only one true event being generated. A polymorphic event in OOA96 (and Executable UML [xtUML02]) results in one and only one true event being generated per subtype-supertype relationship that the polymorphic event's supertype object participates in. However, Kennedy Carter (for Executable UML [xUML04] and Shlaer-Mellor before this) defines significantly different semantics for polymorphic events. They allow a polymorphic event to be received by all state models in the subtype-supertype hierarchy including the initial supertype object. Furthermore, they require that any actions that are performed in a supertype object complete before the polymorphic event propagates down into subtype objects. This definition of polymorphic events is not supported in OOA96, OOA08 or OOA Tool.

A simple example model showing polymorphic events in action is given below, starting with the Object Information Model:

the State Transition Diagram for Main next:

followed by the State Transition Diagram for Child A:

and Child B:

and finally, the Object Communication Model showing communications between Main, Child A and Child B:

Wednesday, 4 June 2008

Attribute Conditionality

OOA91 requires all attributes associated with an object instance to have one and only one value (see first rule of attribution on page 19). However, OOA91 allows these values to be accumulated over time in a lifecycle model (see page 61). Thus, some attributes may not have a value at certain points in time. OOA08 formalizes this property of attributes as conditionality. An attribute must always have a value if it is not conditional, whereas, an attribute may or may not have a value if it is conditional. A (1c) suffix may be used to label attributes which are conditional.

A simple attribute is conditional only if the attribute is explicitly made conditional by the analyst, i.e. by setting Manual Conditional status. Obviously, a simple attribute with an initial value that is final is never conditional. A mathematically dependent attribute is conditional if its value calculation code is not guaranteed to calculate a value or if the attribute is explicitly made conditional by the analyst. A referential attribute is conditional if its associated base attribute is conditional, or if all navigation paths from the referential attribute to the base attribute are conditional or if the attribute is explicitly made conditional by the analyst. Obviously, a referential attribute with a literal value is never conditional. A polymorphic attribute is conditional if any of its true attributes are conditional or if the attribute is explicitly made conditional by the analyst.

Associating an initial value with a conditional attribute still makes sense since OOA08 allows a conditional attribute to be cleared. An attribute with no current value contains a special UNDEFINED (but typed) value. A non-conditional attribute with no associated initial value will be initialized with the default value (if there is one) of the attribute's associated data type when an object instance is created. A conditional attribute with no associated initial value will not be initialized even if there is a default value.

OOA08 (and OOA Tool) requires all Action Language code to strictly obey conditionality constraints. When an object instance is created, all non-conditional attributes must be assigned a value within the enclosing action (if they don't have an initial or default value). If the enclosing action is modelled using a process model then all non-conditional attributes must be assigned a value within the enclosing accessor process (an accessor can access multiple objects in OOA08). This is a much stricter requirement than OOA91 which allows conditionality constraints to be satisfied within actions triggered by events sent from the original enclosing action. The problem with OOA91 is that there is no easy way to determine when conditionality constraints are broken. OOA08 takes the view that conditionality constraints are only useful if they are enforceable.

Saturday, 31 May 2008

Mathematical Dependence

OOA96 added the concept of mathematical dependence and mathematically dependent attributes to information modelling. Such attributes are annotated with an (M) suffix and are known as derived attributes in most other object-oriented methods (including Executable UML). Although the term mathematically dependent is a mouthful and the alternative term derived is much easier to use, it does allow us to distinguish between the analysis and design/implementation concept of derived.

When mathematically dependent attributes are calculated depends on the software architecture. They may be calculated on demand, i.e. whenever their value is accessed. Alternatively, they may be calculated whenever their dependent attributes change and then cached for instant access when needed. However, Recursive Design in OOA08 allows attribute updated mappings to be created in bridges that execute action language code whenever an attribute changes. If such a mapping is made from a particular mathematically dependent attribute then the second approach must be implemented for that attribute.

OOA08 also allows mathematically dependent relationships which are a new type of binary relationship formalized using action language code. Code needs to be provided for navigation in both directions. This code is given an instance of the source participant and returns a set of corresponding instances of the target participant. Using mathematically dependent relationships, analysts can now define composed relationships of the form R1 = R2 - R3 etc.

Thursday, 29 May 2008

Referential Attributes

Referential attributes are used to formalize binary and associative relationships. All objects should have one or more identifiers each of which is composed of one or more identifying attributes. Any attribute on an object can be identifying. It is common for identifiers to be composed of more than one identifying attribute. Some analysts get lazy and create arbitrary ID identifiers everywhere but I try to avoid them whenever possible. To formalize a one-to-one or one-to-many binary relationship between two objects (or participants), a target identifier is chosen on one object and a set of referential attributes are chosen (or added) to the other object where each referential attribute is mapped to an identifying attribute of the target identifier. These referential attributes can't be set directly by the analyst, they exist only as a by product of a relationship instance existing. A referential attribute may be used in many participant mappings each of which is annotated in the referential suffix.

OOA08 (and OOA Tool) fully supports the use of referential attributes to formalize binary and associative relationships. However, OOA08 requires all referential attributes be resolvable to a single base attribute (non-referential and non-polymorphic). This wasn't an explicit requirement in OOA91 or OOA96. An analyst could keep a model consistent by using the same data type (or attribute domain) for overlapping referential attributes. However, in my experience it is always possible to resolve overlapping referential attributes to a single base attribute and the resulting model is always more complete.

As a result of this requirement, all referential attributes have a base attribute status of either:

  • Unresolved indicating that there is no path from the referential attribute to any base attribute,
  • Partially Resolved indicating that there is a path from the referential attribute to a base attribute but that there are also other non-circular paths which don't lead to a base attribute yet,
  • Fully Resolved indicating that all paths from the referential attribute lead to a single base attribute (ignoring circular references),
  • Incompatible indicating that one or more paths from the referential attribute lead to a base attribute with a data type that doesn't match the manual data type associated with this attribute (which can't happen if a manual data type is not specified),
  • Multiple Base Attributes indicating that one or more paths from the referential attribute lead to multiple base attributes (whether they have the same data type is not relevant in OOA08),
  • and Only Circular References indicating that all paths from the referential attribute are circular in nature.

The example above should help illustrate the different base attribute statuses. Attribute A1 is Unresolved since it is declared as referential but doesn't appear in any participant mappings. Attribute A2 is Unresolved since although it references Attribute B1, that attribute is Unresolved. Attribute A3 is Partially Resolved since although it references Attribute B2 which is a base attribute, it also references Attribute C1 which is Unresolved. Attribute A4 is Fully Resolved since it only references Attribute D1 which is a base attribute. If Attribute A4 had a manual data type of Integer and Attribute D1 had a manual data type of String then Attribute A4 would have an Incompatible status instead. If Attribute C1 was a base attribute rather than a referential attribute then Attribute A3 would have a Multiple Base Attributes status instead. If Attribute B1 formalized relationship R4 then both Attribute A2 and Attribute B1 would have a Only Circular References status.

Circular references are common when composed identifiers are used, i.e. the identifiers for a set of related objects may all have a common identifying attribute. Having circular references is not a problem unless there are only circular references. However, once a referential attribute with this problem has been identified, it can normally be easily fixed, i.e. a set of related objects with a common identifying attribute implies a relationship should exist to an object defining the common attribute as a base attribute. There are situations that appear to be correct but which still have referential attributes with only circular references, i.e. when an identifying attribute which should have been a base attribute has become a referential attribute. However, an analyst should always be able to determine the home object of a referential attribute and if that attribute is not a base attribute, the analyst should make it a base attribute by separating the referential duties off into another attribute and noting the constraint.

The algorithm for resolving base attributes is highly iterative because referential attribute mappings form arbitrary graphs which may be cyclic, i.e. they may include circular paths. The algorithm is briefly outlined below:

  1. Add all referential attributes to a set of unresolved referential attributes
  2. Loop thru the set of unresolved referential attributes until a complete iteration occurs without resolving a single referential attribute
    • Attempt to resolve the base attribute and base attribute status of each referential attribute using previously resolved referential attributes (or previously determined true attributes for polymorphic attributes) while checking for error conditions at the same time
    • If any unresolved referential attributes are referenced by this attribute then skip the resolution of this attribute for now
    • A base attribute status can be resolved if all references from this attribute are non-referential attributes, previously resolved referential attributes or if an error condition can be detected without the need to completely resolve all references from this attribute, e.g. for Incompatible or Multiple Base Attributes error conditions
    • If a base attribute status can be resolved then remove this attribute from the set and perform another complete iteration of the unresolved referential attributes after this iteration completes
  3. If the set still contains unresolved referential attributes then a final iteration thru the set is made re-enter the above loop, except that references to unresolved referential attributes are treated as circular references and ignored
  4. Any unresolved referential attributes after this final iteration are all given the base attribute status of Only Circular References

The data type of a referential attribute is determined from the resolved base attribute. However, a manual data type can be specified for a referential attribute for consistency checking purposes. An error condition will be flagged if the resolved base attribute's data type doesn't match the manual data type.

The conditionality of the referential attribute is determined from the resolved base attribute's conditionality along with the navigation conditionality across all the paths to the resolved base attribute. This can also be weakened by specifying a manual conditionality for the referential attribute. Further discussion of attribute conditionality will be left for another day.

Monday, 26 May 2008

Polymorphic Attributes

Polymorphic attributes are new to OOA08 and have only really become useful since OOA96 introduced mathematically dependent (i.e. derived) attributes. Previously, if a common non-identifying attribute was defined in most (not necessarily all) subtypes of a subtype-supertype relationship, it would be abstracted into the supertype object. This would only cause a problem if the attribute was referential in any of the subtype objects. In which case, the analyst would have to leave the referential attributes where they were and decide whether having a copy of the attribute in the supertype object was still beneficial. OOA96 introduced the concept of a constrained referential attribute and this could be used to constrain any referential attributes left in subtypes after a common attribute is abstracted into a supertype object. This situation does not happen often in my experience. However, with the introduction of mathematically dependent attributes, abstracting common attributes of mixed type becomes much more difficult. How do you abstract a common attribute which is a simple attribute in one subtype and a mathematically dependent attribute in another subtype? The answer is a polymorphic attribute.

Polymorphic attributes are similar to polymorphic events (which were also introduced in OOA96) in that polymorphic attributes in a supertype object are mapped to true attributes in subtype objects. An analyst associates a subtype-supertype relationship with a polymorphic attribute and then selects a subtype attribute in each of the relationship's subtype objects. Subtype attributes may themselves be polymorphic attributes. When we refer to true attributes we mean non-polymorphic attributes with any intermediate polymorphic attributes flattened out. Obviously, the object containing the polymorphic attribute must be the relationship's supertype object. It is rare for there to be more than one choice of subtype-supertype relationship, i.e. multiple supertype objects are rare.

Polymorphic attributes and their corresponding true attributes do not have to have the same name but they must have the same data type. However, OOA Tool can pre-select subtype attributes that have the same name and data type. This makes the creation of a polymorphic attribute a 2 second job in most cases. The conditionality of a polymorphic attribute is the weakest conditionality of any of it's true attributes, i.e. the polymorphic attribute is conditional (1c) if any true attribute is conditional. Furthermore, an analyst can make a polymorphic attribute conditional even if none of it's true attributes are conditional. One could argue that the data type of a polymorphic attribute should be the weakest data type of any of it's true attributes. However, to keep things simple, the data types of all true attributes must match in OOA08.

The example above shows a typical polymorphic attribute with a true attribute defined in each of the subtype objects. The attribute suffix of a polymorphic attribute begins with 'P' and includes the associated subtype-supertype relationship ID, e.g. (P-R1). Using the relationship ID is important since the associated relationship may be defined in another subsystem and thus may not be shown on a particular diagram. The attribute suffix (P) is used if there is no associated relationship at present. In the example above the true attributes are simple, mathematically dependent and referential.

Polymorphic Attribute above could be replaced by Other Attribute if the associated calculation code performed a simple switch on the supertype's current subtype returning the appropriate true attribute value. This would be unthinkable in an object-oriented programming language. However, in Shlaer-Mellor OOA, a subtype-supertype relationship is complete in the sense that all subtypes are identified by the analyst in the information model. Therefore, the switch code for Other Attribute would also be complete. OOA Tool will inform an analyst if a subtype switch statement is no longer complete, e.g. when a new subtype object is added. The disadvantage of using this approach is that the polymorphic relationship is hidden in Other Attribute's calculation code.

The diagram above shows how polymorphic attributes can be used to create interface like objects without having to create additional redundant relationships or use arbitrary IDs. Main ID and Parent ID in Interface would normally have to be referential attributes but that would require some form of relationship to Parent to resolve the referential attributes (OOA08 requires all referential attributes to resolve to a single base attribute). Alternatively, an arbitrary ID could be added to Interface and then used in Child B and Child C. Making these attributes polymorphic means that they can resolve downwards in R3 while the matching attributes in Child B and Child C reference upwards to formalize R3. This works because the matching attributes in Child B and Child C have an alternative path to their base attributes in Parent and Main. How referential attributes are resolved to base attributes and why they should all resolve to a single base attribute will be discussed another day.

Friday, 23 May 2008

Flattening Subtype-Supertype Hierarchies

One of the first tasks when mapping (or translating) Shlaer-Mellor information models to XML documents or Java code is to flatten subtype-supertype hierarchies. Obviously, XML does not support any kind of generalization. While Java only allows single inheritence and this facility may be required to implement the objects within the Java software architecture.

The diagram above shows leaf objects with single and multiple supertypes. The definition of a leaf object is any object which doesn't participate in a subtype-supertype relationship as a supertype object. This example is easily flattened into:

  • Leaf A containing Leaf A and Supertype A
  • Leaf B containing Leaf B, Supertype A and Supertype B
  • Leaf C containing Leaf C and Supertype B

The diagram above shows an example of an improper subtype-supertype relationship. Leaf B is a subtype of Supertype B and Supertype C. However, the subtype-supertype relationship R1 specifies that all Supertype A objects are either Supertype B or Supertype C but not both. Executable UML (the UML version of Shlaer-Mellor) explicitly labels these relationships as disjoint to emphasis the point. C++ allows multiple inheritence with common base classes but Shlaer-Mellor OOA does not.

The other form of improper subtype-supertype relationship is where a subtype ends up being a supertype of itself via a circular chain of subtype-supertype navigations.

The diagram above shows an example of compound subtype-supertype relationships where Supertype is a Leaf A or Leaf B and a Leaf C or Leaf D. To flatten this example requires the introduction of new compound leaf objects:

  • Leaf A/C containing Leaf A, Supertype and Leaf C
  • Leaf A/D containing Leaf A, Supertype and Leaf D
  • Leaf B/C containing Leaf B, Supertype and Leaf C
  • Leaf B/D containing Leaf B, Supertype and Leaf D

Compound subtypes may participate in other subtype-supertype relationships either as supertypes or subtypes leading to complex hierarchies. However, as long as there are no improper subtype-supertype relationships then these hierarchies can always be flattened into leaf and compound leaf objects.

The algorithm for flattening subtype-supertype hierarchies gave me a few headaches before I settled on a two pass strategy:

  1. The first pass iterates over all leaf objects (non-supertype objects) creating flat elements each containing a set of component objects (as shown in the examples above). This pass uses limited recursion when navigating to supertypes and can easily check for improper subtype-supertype relationships by checking whether an object has already been added to a flat element's set of component objects prior to adding a new object.
  2. The second pass iterates over all multiple supertype objects (non-leaf objects which are supertypes in multiple subtype-supertype relationships). It then matches each subtype object to all flat elements whose set of component objects contain the subtype object. The set of flat elements for the subtype objects in each of the subtype-supertype relationships are then multiplied out by creating new flat elements containing the combined set of component objects (ignoring duplicates). The new flat elements replace the previous flat elements before the second pass iteration continues. This ensures multiple compound subtype-supertype relationships are correctly flattened without the need for recursion in this pass.

All flat elements contain at least one leaf object. A flat element containing multiple leaf objects represents a compound leaf object. A suitable name may need to be chosen for compound leaf objects since they aren't explicited defined in Shlaer-Mellor information models.

Flat elements can be easily mapped to XML elements as long as a suitable name for compound leaf objects can be determined. The XML attributes for the element are determined from the combined attributes of the flat element's set of component objects. All simple attributes except Arbitrary ID or Ordinal ID attributes are required. Mathematically dependent attributes may be useful but are not absolutely required. All referential attributes used solely to formalize subtype-supertype relationships can be ignored. Referential attributes used to formalize containment relationships can also be ignored. Only referential attributes used to formalize referential relationships need to be considered. All polymorphic attributes can be ignored since the true attributes must also be present. Attribute names may need to be qualified when they are mapped to XML attribute names. I will leave the discussion of containment and referential relationships within XML documents to another day.