Several design patterns propose techniques for supporting the dynamic modification of a method or interface. In this section, we present the notion of dynamically altering the behavior of an object by attaching contexts to it. An object may have many contexts attached to it, with each context altering one or more method implementations for the object.
Figure 7: Composition class using context relation
Implementing the context relation requires language support for (1) indicating whether a method is an instance-stored method or a class-stored method, (2) allowing a context class to define method implementations of its base class, termed method update, and (3) dynamically altering a method implementation, through context attachment. The context relation itself may be inferred from the class body. The C++ code in Figure 7 demonstrates the new program constructs for implementing the context relation. The Compositor class and its associated inheritance hierarchy are no longer necessary.
To achieve method update, we extend the standard class construct. A class defines data members and methods, and may redefine methods for its base class. The Composition base class defines method Compose as an instance-stored method, indicating each Composition class instance may vary the implementation of this method. The SimpleCompositor, TextCompositor, and ArrayCompositor classes define implementations of the Compose method of the Composition class. The implementation invoked when a Composition object receives a Compose message depends on whether an instance of the SimpleCompositor, TexCompositor, or ArrayCompositor class has been attached. Note that a Compose message may be sent only to Composition objects.
To achieve context attachment, we propose the operator
When an object is first instantiated, its behavior is defined by its static
class definition. This may be dynamically altered by attaching contexts. The
context relation introduces a new type that is inferred from the class model.
We use Composition:: to describe the set of classes that are context-related
to base class Composition. The context classes update the Compose
method of the Composition class, with the implementation given in the
SimpleCompositor class defined as the default. The
Composition constructor will attach a context object passed in as an
argument to the newly created Composition object. The expression
this ::+ comp; alters the Composition object by updating the
Compose method implementation to be that defined in the context class.
Context attachment may alter a method implementation, which may refer to attributes and methods of either the base class or the context class itself. Thus, when a message is sent to an object, the method implementation should be executed on the receiver object as well as the context object. The self reference ( this pointer in C++) refers to the receiver object. Additionally, it is useful to have a reference to the context object defining the method implementation. We call such a reference context. Executing the method on both the receiver and context will provide a means for simulating dynamic extension of the data members of the receiver class. As will be shown with the Visitor pattern, executing the method on the receiver and context also allows sharing of state among collaborating objects.
The State design pattern allows an object to change its behavior based on its internal state, where state represents a partitioning of data member values. An object in different states may react differently to the same message. The essence of the state pattern is to define a relation between the attribute values of an object and its behavior. This is modeled in OMT through the conceptual link between the object model and the dynamic model . However, the translation of the dynamic model into a corresponding class-based model usually turns the relation into aggregation and inheritance. As with the strategy pattern, the state pattern is poorly modeled using aggregation and inheritance. To remedy this, the context relation is used to link a class and its alternative state-based implementations. The Adapter, Bridge, Chain of Responsibility Decorator and Observer design patterns can likewise be improved by using the context relation.