Imagine you are creating a game that contains many different classes of things; there are players, monsters, and objects that can be picked up. In addition, magic spells can change the classification of things for a set time period. A monster might transform into an object that can be carried, or an object might pick itself up and walk around like a monster.
Implementing this sort of arrangement with a traditional inheritance hierarchy and data-driven attributes is a difficult housekeeping task, as things must transform back to their initial characteristics as soon as the spell ends or is dispelled. If every new spell implementation required the developer to modify all of the methods of the game's physics model to check for the existence of each enchantment, the application would quickly become unmaintainable. It would also prove difficult to find all of the source code associated with any existing spell, as said code would be scattered throughout the application. A better paradigm is needed that allows the common effects of each spell to exist together in one class that can be used to change the effect of many diverse methods throughout the application.
Dynamic Behaviors, a design pattern similar to the Chain of Responsibility pattern, is ideally suited for applications that must change the class of objects fluidly at runtime. MacApp 3.0 used behaviors to implement dynamic "adorners" that could be used to change the way objects in the user interface were drawn. The C++ implementation relied on multiple inheritance and pointer fields inside the behavior objects themselves. This article presents a more flexible alternative that allows the same behavior to modify multiple objects without relying on multiple inheritance or other features unavailable in Java.
This implementation's design puts a high premium on the simplicity of defining new behavior classes; applications that need behaviors may require numerous classes, so they should be as easy as possible to write.
Java is not a dynamic language; to simulate a dynamic language's features in Java, you must add a certain amount of "glue"
to each class method that may be modified by appending behaviors to that class's object instance. To do this, first split
method foo() into two methods: foo() and fooDefaultBehavior(). foo() is called the dispatch method and fooDefaultBehavior() is the default behavior method (naturally enough).
Figure 1 shows the flow of control involved. When a caller invokes the method foo(), conceptually, she expects to execute the code in the default behavior method. If behaviors are attached to the object, though,
they are each allowed to override foo()'s behavior; they are able to perform different operations, invoke the default behavior, and modify the returned result.

Figure 1. Dynamic Behavior flow of control
The foo() method first creates a behavior iterator and then dispatches to the first object in the behavior chain. The objects in the
behavior chain contain methods that all take the behavior iterator as their first parameter and use it to obtain a reference
to the next behavior in the call chain. When the foo() method creates the iterator via getInheritanceChain, it initializes the iterator such that fooDefaultBehavior() is the last behavior in the chain. There is always a terminating default behavior, even if it does nothing. Behavior objects
can rely on this invariant and always call the next behavior without checking for null pointers, which simplifies the code.
Archived Discussions (Read only)