Added by Johan Stuyts, last edited by Johan Stuyts on Sep 12, 2006

Labels:

Enter labels to add to this page:
Wait Image 
Looking for a label? Just start typing.

Double Dispatch Association - Behavioral

Full text

Intent

Manage bidirectional associations from both ends while allowing interface-based programming.

Motivation

Associations, implemented as references, are unidirectional in object-oriented programming. A bidirectional association that is consistent has to be implemented by the developer. There are many ways to do this. Below is a list of requirements for a high-quality association management solution.

No matter what implementation is chosen, one important quality is that the association can be managed from both ends. For example, adding a child to a parent and setting the parent of a child, must result in exactly the same state.

To allow additional functionality to be added to objects without having to change the clients, objects must be accessed using interfaces. The implementation for association management must support this. In fact, Double Dispatch Association is based on this requirement.

The interface of the objects should not be polluted with implementation methods for association management. This makes it easier to use the interface, and prevents accidental invocation of an implementation method. Please note that overloading a method name is acceptable because no new identifiers are introduced, but even overloading should be kept to a minimum.

Association management methods must be simple. The only complex part of the association management methods must be the code to validate that an association can be made or broken, i.e. the business rules must be checked. There are two problems with association management that have to be implemented as simple as possible: infinite recursion and type checking.

A basic implementation for association management can easily lead to infinite recursion. The client calls the first object, which calls the second object to complete the association, which calls the first object to complete the association, etc. For example: p.addChild(c), c.setParent(p), p.addChild(c), etc. This must be prevented, of course. Using conditional statements to check whether or not the current invocation is the result of a previous invocation of the same method seems logical, but it is too cumbersome, and even worse it is very likely that it is not possible because the method does not have enough information to determine this.

Infinite recursion is easily prevented by separating the bidirectorional association management from the unidirectional association management (the reference management). Bidirectional association management methods can invoke reference management methods, but not the other way around. This way there are no recursive paths in the association management code.

Because interface-based programming is a requirement, the associations are made between interfaces and not implementations. The implementations must translate this to association between implementations. The parameters cannot be cast to the correct type without a type check because a client might provide an invalid implementation of the interface. A conditional statement could be used for the type check but this is too cumbersome and verbose. Double dispatch solves this very nicely by not requiring the use of a conditional statement but by using the implicit type information of the thisreference.

The list of requirements for association management is quite long so it is hard to come up with a solution that satisfies all requirements. Double Dispatch Association is a solution that does, ensuring associations can be made reliably with clean APIs.

Implementations

No reusable implementations of this solution are available because each application needs its own set of unique objects.

Nice article thanks.

Posted by Anonymous at Jul 23, 2008 09:48