3.5 Invariants and encapsulation

We have seen already that cyclic associations imply invariants and that bi-directional associations violate the principle of encapsulation and are therefore incompatible with object-orientation. The object-oriented principle of encapsulation implies that bi-directional associations must be abandoned in object-oriented modelling, in favour of either uni-directional pointers or conversion to bona fide classes.

In our formalism as we have seen, objects encapsulate rulesets, along with the usual attributes and methods. To maintain the principle of encapsulation, objects must have rulesets; they are not an optional extra.

Most of the popular first-generation methods for object-oriented analysis (e.g. Coad and Yourdon, 1991; Rumbaugh et al., 1991; Shlaer and Mellor, 1988) and several of the less widely used ones offered a construct that placed a link between object types depicting static connexions other than generalization and composition. This construct is generally called an association. Some authors use the term 'relationship' as its synonym; whilst yet others use 'relationship' as a higher level abstraction which groups together association, usage, aggregation, collection, various flavours of inheritance, etc. Such associations describe one aspect of the connectivity between object types. This approach is familiar to most developers who have used entity-relationship techniques and is semantically identical since these associations refer only to the data structures of the objects and not to their behaviour (except in those rare instances where associations are used to denote messaging; e.g. object-oriented SSADM (Robinson and Berrisford, 1994)).

A study of the literature of semantic data modelling reveals that there are two fundamental ways to connect data structures or entity types: constructors and pointers. Delobel et al. (1995) explain that in the first approach, emphasis is placed on building structures using constructors such as the tuple or the set. In the second, the stress is on linking types using attributes. In the 1980s the former approach was dominant, largely because of the popularity and widespread use of relational databases. In entity-relationship models there are two logical types: entity-relationships and relationship-relationships. Both are represented by sets of tuples and no links between them are stored; the run-time system of the DBMS must search for the linkages. Attempts to enrich the relational model led quickly to systems with more than two relationship types. This unsatisfactory situation soon led to suggestions to replace these arbitrary type systems with a single notion of classes reminiscent of object-oriented programming. The pointer-based approach is far more natural to an OO thinker but one suspects that the popularity of methods such as OMT was due largely to the fact that developers with a relational background found its approach familiar and anodyne. The danger here is that object-oriented principles will be ignored and highly relational models produced instead of truly object-oriented ones.

Associations as types

We think that associations should point in one direction only because to do otherwise would violate the principle of encapsulation. Several object-oriented methodologists have argued against our position, saying that you can always add link attributes to an association and create from it an association object type. However, this new object type must retain links to its progenitors. Therefore, if we accept this as a solution, these new relationships must in turn give rise to new association object types. At some point we must stop this process and will still have to represent the residual associations connecting our, now more numerous, set of classes. This is not to deny the utility of association object types. Some associations are so important that they are themselves concepts; i.e. object types. An often quoted example is the marriage relationship between people, discussed below.

Of course, in any particular case, one can find a natural place to stop this process. It is usual to create types out of associations only when the association has interesting properties in its own right. This still leaves us with associations between the newly constructed types and the types that were previously linked by the original associations. Thus, in all practical cases, we will have failed to convert all associations to types although we will typically have removed all the many-to-many associations through this process. It is worth noting that while relational databases forbid the use of many-to-many relationships, they are not precluded by modern object-oriented databases. Thus the habit of always removing them, common among traditionally educated database designers, is no longer necessarily a good one.