Last week we got our single behavior menu working. This week we have a new challenge, we need our fish to be able to exhibit a combination of behaviors. However, this becomes a problem if we are to follow our general design rules: 1) If it's not broke, don't fix it. 2) K.I.S.S. (Keep it simple, stupid!) Our fish works well and we have no errors in it, it also has the ability to represent a behavior. So it's probably not a good idea to go in and start adding variables and mucking up our original and quite elegant design. Thankfully, this problem of needing to represent combinations of behaviors occurs quite frequently... we should look at the Design Pattern archive and see what the “Gang Of Four” has to say. After some research we find out that this problem has been solved before, it is solved using the "Decorator" design pattern. http://www.exciton.cs.rice.edu/JavaResources/DesignPatterns/DecoratorPattern.htm If we look at our assets we see that we need to properly leverage Polymorphism using our Behavior class to solve this problem. If we create a new class called Decorator that implements the Behavior Interface and "Knows" two behaviors, we can write a behavior that delegates to two more behaviors. This delegation will give the appearance of "multiple" behaviors. //Our Decorator is a behavior, so use Realization. public class Decorator implements Behavior{ private Behavior _beh1, _beh2; //Write the association relationship for the behaviors //because our decorator needs to know two behaviors. public Decorator(Behavior beh1, Behavior beh2){ _beh1 = beh1; _beh2 = beh2; } //In order to be a "Behavior" we must define all methods //that are declared in the Behavior interface. public void update(Fish fish){ //delegate to two other behaviors. _beh1.update(fish); _beh2.update(fish); } } So, to use our newly created decorator class, we would write something like the following inside our fish. _behavior = new Decorator(new Dizzy(), new Chameleon); Now our fish exhibits both the Dizzy and Chameleon behaviors simultaneously. But wait... the menu has 3 behaviors that we can check and uncheck, our decorator only allows us to have two. How do we solve this conundrum? Well, by properly leveraging polymorphism this problem become trivial. If you recall, Decorator implements Behavior, so we can pass another Decorator into the original instance. Using this technique we can add behaviors ad nauseam. _behavior = new Decorator(new Dizzy(), new Decorator(new Chameleon(), new RandomSwim()); … But what about the Leader and Follower menus? Originally, I thought to myself and I told you that this was a good job for a “Holder”. But after reconsidering the job, I think Holder is kind of overkill. I think that a /static/ variable would do nicely! Now you may ask… What does the keyword “static” do ? And I will answer… the following! When the Java Virtual Machine loads a class into its environment, if the class contains any static methods or variables it creates two entities for the class. The “instance” which is the entity we have used all semester and the “class” entity which contains information that doesn’t change from instance to instance and allows us to make Method Calls using the class name. Recall this functionality from both the NGP.Utilities class; You never created an instance of Utilities but you were able to call the getRandomColor() method using the syntax ClassName.methodName() [ie. NGP.Utilities.getRandomColor()] We can have multiple “instances” of an object, but there will only be one “class” entity in the Virtual Machine. To create a static method we use the following syntax. public class Example{ public static Behavior getBehavior(){ return new Behavior(); } } To call this method we would type: Example.getBehavior(); If we access or mutate an instance variable inside of a static method, that variable must be typed as static too. The syntax for a static instance variable is as follows: private static Behavior _dizzy; So for our Leader Fish… in the LeaderMenu class we need to create a static instance variable of type fish. Then we have to create both a static accessor and a static mutator to changes who the leader fish is. Then you have to create a “follower behavior”. This follower behavior should use the static accessor to get the leader fish.