From these requirements we have derived a design pattern that must be followed by the agent programmer developing mobile agents using dynamic adaptation as presented in this work. Note that this limits the application area of dynamic adaptation to OO technology. The use of several environment-dependent implementations alongside each other is known as strategy pattern [GHJV95], which can be implemented through an abstraction via interfaces. The agent programmer must define an environment-independent interface which is implemented by all implementations providing single functionality for multiple environments.
We also refer to the environment-independent interface as functionality interface and to the environment-dependent class as implementation class. The core idea is obviously that only functionality interfaces are exposed in application-specific code, and that the adaptation framework takes charge of bringing the right implementation classes into play. The functionality interface is specified by the agent programmer and the implementation classes for different environments implementing the functionality interface are developed by the component developer. Classes implementing the same functionality interface form an implementation group, and adaptation essentially performs environment-directed searches within the scope of each group.
We put an adaptor class in place to achieve flexible control of the relationship between a functionality interface and its candidate set of implementation classes; it is the place where adaptation ``strategy'' (as in strategy pattern) is decided. An adaptor is similar to a Corba or RMI stub, providing an extra level of indirection between its two clients. Adaptors are concerned with the appropriate delegation of method calls from functionality interfaces to implementation classes.
Code for adaptor classes can be generated from functionality interface descriptions, and we provide a corresponding tool with our prototype implementation (see section IV).
In the example of the browser configuration, the mobile agent needs to acquire system information such as the size of physical memory. By way of our example, operating-system and CPU-architecture-specific implementation classes are needed for this information retrieval. There are environment-dependent implementation classes for every supported environment. The agent programmer defines the functionality interface IMemory with a method getPhysicalMemory() which is then implemented by all implementation classes in the same implementation group, thereby accounting for physical memory size in different ways.
Fig. 4 shows the usage of the adaptor class in the example application. The adaptor IMemory_Adaptor is used in the core of the mobile agent for accessing information about the memory situation. This adaptor is derived from the functionality interface IMemory by an automatic step, as explained. The core moves without implementation classes, but with the adaptor over the network. When it comes to a new host the adaptor initiates adaptation by calling library code context awareness and reconfiguration which loads the suitable class, in this case the implementation class Memory_PPC_AIX.