next up previous
Next: Separating interface and Up: Related Work Previous: Evolving Object Interfaces

Evolving Collaborative Behavior

Many tasks require the collaboration of a group of objects. Researchers have acknowledged the need to lift abstraction above the class level, and several approaches have been proposed for modeling collaborative, task-based behavior, including Frameworks [10], Clusters [16], Mechanisms [3], Contracts [8,9], Propagation Patterns [27,12], and Subjects [18].

As an example, a Contract [8,9] models a set of object interactions. The participants of the contract have certain obligations (attributes and behaviors) that they must support. A contract defines a template of participants and obligations of a task, and is reused by instantiating and enabling the contract, attaching each participant role to an object and obligations to specific properties of the object. When an object is sent a message, its active contracts determine its behavior. While an object may participate in several contracts simultaneously, it may not participate in multiple contracts that define the same method. Additionally, the method implementation defined in a class hides that defined in a contract. Thus, it is not possible to dynamically alter an existing class method. With contracts, one must specifically attach (activate, enable) a participant role to a particular object in order to modify its run-time behavior. A context class may be related to several base classes, thus serving to define a collaborative, task-based style of programming, as was presented with the visitor pattern. With our context mechanism, it is possible to implicitly alter many objects by call attachment.

An additional difference arises from the composition mechanism, which is the process of creating new components from existing ones. Propagation patterns [12] provide an adaptive approach to collaborative behavior, in that behavior is defined in a manner that can be reused with many class structures. A propagation pattern consists of (1) a signature, (2) a propagation directive, which is an adaptive specification of object navigation similar to the traversal expression that we have presented, and (3) a set of code wrappers, which describe task-specific behavior to be executed during the object navigation. A code wrapper maps code to classes to be executed during traversal. As an example, Figure 24 contains the Pricing and Inventory visitors rewritten as propagation patterns. A propagation pattern combines a traversal function with the behavior that should be executed as class instances are encountered during the traversal. Notice that the propagation pattern is not a class definition, rather it should be thought of as a set of functions or methods. Thus, any calculated values such as the value must be passed along during traversal in the form of an argument parameter. This requires the client to initialize the value before the traversal is initiated. The main program calls each propagation pattern by invoking a method of the same name for the computer object.

Figure 24: Pricing and inventory visitors as propagation patterns

Notice that two separate traversals must occur to compute the inventory and pricing visitors, since the propagation directive is a fixed part of each propagation pattern. A propagation pattern directly pairs an adaptive traversal specification with a particular task. We separate the two, allowing adaptive traversal specifications to be reused with many tasks.

To execute both visitors during a single traversal, the propagation directive would have to be removed from one of the propagation patterns, which would be converted into a Transportation Pattern [13]. The two visitors could then be composed by injecting the code wrappers from the transportation pattern into the propagation pattern. The composition mechanism used with propagation patterns, namely transportation pattern inclusion, suffer from the same problem found with many approaches, including contracts. Specifically, when component inclusion is implemented by simply copying code, naming issues arise when a component is included into another more than once or if two included components overlap in named elements. While not a problem with the example pricing and inventory visitors, a problem would arise if they had both chosen to use the same name for their formal argument, rather than and .

As the context construct is an extended class definition, the inheritance and aggregation relations may be used for class-level composition. At the dynamic object level, both incremental and overriding method update are possible. As a context object scopes its attributes and methods, incremental composition will not result in naming issues.

next up previous
Next: Separating interface and Up: Related Work Previous: Evolving Object Interfaces

Karl Lieberherr
Tue Jan 21 09:24:10 EST 1997