Skip to main content

Notice: this Wiki will be going read only early in 2024 and edits will no longer be possible. Please see: for the plan.

Jump to: navigation, search



Navigate in a context from one object to another without creating and maintaining references between the objects in this context.

Also Known As

Virtual Navigation.


In order to implement a collaboration in a given context, objects may need to have references to each other. To create and maintain such references is not only cumbersome but may also lead to duplication of references which are already existing in another context between the same objects.

When the given context can access the references already existing in another context through objects being part of both contexts, this can be used in the navigation to avoid unnecessary duplication. This applies not only to direct references but also to any references which can be obtained by repeatedly making calls to objects already referenced directly.


This pattern requires a set of objects which need to collaborate in some secondary context. These objects are semantically dependent on objects in some primary context. In the primary context, these objects can access each other in some way either through direct references or through references computed by services they provide to each other. The references needed in the secondary collaboration can all be mapped to either a direct reference or a computed references in the primary context.

Not only simple references are covered by this pattern but also references to array types.


We describe the idea of the pattern with two objects which are collaborating in two different context. For simplicity, one of the contexts is a base context. The secondary context is semantically dependent on the base context. We only present the navigational part of the dependency but we do not present how the dependent context otherwise depends on the base context.



  • B1: This base class provides access (getOther()) to an entity of the base class B2.
  • B2 This base class can be accessed by class B1.
  • R1: This role class is semantically dependent on the base class B1. To implement its own functionality, it needs to provide a method getOther() which returns a reference of type R2.
  • R2: This role class is semantically dependent on the base class B2. It offers some functionality to the other role class R1.
  • NavigationContext: This team encapsulates the collaboration of the two roles. In this context, the navigation is accomplished.


The role class R1 implements a service which returns a reference of role class R2. In order to obtain such a reference it uses a service getOther() of the base class B1. Because R1 adapts B1 through the playedBy relationship, it can access all services of that class as a callout ((OTJLD §3), i.e., as if it was calling them on itself. Therefore,

  • an abstract method getOther() has to be declared with the desired return type of role class R2,
  • the method is bound by a callout to getOther() on the base.

Due to this binding the return type B2 is automatically lifted (OTJLD §2.3) to the role type R2.


Role R1 need not store a reference to its acquaintance R2, but can reuse the existing link B1->B2.

Navigation will involve lowering, as method call to the base object and lifting, which might affect performance.


As an alternative to the pair of abstract method declaration and callout binding, also a short-hand callout binding (OTJLD §3.1.i) can be used.

Sample Code

The normal implementation in OT/J looks like this:

public team class NavigationContext {
  protected class R1 playedBy B1 {
    abstract public R2 getOther();
    getOther -> getOther;
  protected class R2 playedBy B2 {
      // application specific code

Known Uses

  • BrowserDemo (unmaintained example)

... (many uses exist, must mine for most illustrative example).

Related Patterns

Back to the top