I'm working with students in my Java class on a simple Zork-like environment in which the player goes from location to location encountering items. The items should have dynamic behaviors, so that a book is readable until you burn it, or a duck can fly until it flies too long and tires out. And so on.
The students and I have grokked the basic Strategy pattern (I'm adapting from Head First Design Patterns, and leaving out boilerplate):
public class Duck {
String name;
Int health;
FlyBehavior flyBehavior;
public void performFly() {
flyBehavior.fly();
}
public void setFlyBehavior(FlyBehavior f) {
flyBehavior = f;
}
}
public interface FlyBehavior {
public void fly();
}
public class FlyGracefully implements FlyBehavior {
public void fly() {
System.out.println("I fly so gracefully!");
}
}
public class TooTiredToFly implements FlyBehavior {
public void fly() {
System.out.println("I'm too tired to fly.");
}
}
Sparing the details of the main
method, this lets us switch different flying behaviors into our Duck. This is easy because it returns a void and prints to sysout.
But what if we need the behavior to interact with the state of the Duck? Let's say that:
- When the duck becomes too tired to fly, its name changes to "Exhausted Duck." Other behaviors can change its name, too.
- When the duck is attacked (gonna happen), its health goes down. When its health is too low, its flyBehavior switches out to the TooTiredToFly behavior.
But I'm assuming that dynamic behaviors, at least in this pattern, have no access to the state of the object they're in.
Is there a general strategy for creating dynamic behaviors that interact with the state of the object they're in? I would like to teach something comprehensible, so put yourself in the mind of intermediate-level high school programmers.