Home > Assignments > Recipe for Success: Implementing the State Pattern

Recipe for Success: Implementing the State Pattern

The State Pattern – Allow an object to alter its behavior when its internal state changes. The object will appear to change its class.

Implementing the State Pattern:

  1. Fortunately, the State Pattern is a simple concept, and it’s uses are obvious. To implement the pattern in your project, you must first find something that may have various states. This is no complex task; a state is something as simple as Hungry, Tired, Angry, Alive, Dead, Sleeping, Attacking, Defending, Running, Walking, Stationary (Immobile), Waiting, etc. You want to make sure that whatever you choose has more than one state; if it only has one state, then it’s not really a state to begin with, but it’s rather the definition of what that object is.
  2. Now that you’ve found a Finite State Machine (something with multiple states), you need to decide explicitly what those various states will be. For example, you’ve decided a dog will be your FSM (Finite State Machine), then perhaps the states of the dog could be Hungry, Tired, Sleeping (quite a lazy dog).
  3. Now decide what within your FSM (our dog) changes depending on the state that it’s in. For example, if our Dog was in a Hungry state, it might look for food, but if it’s in a Tired state, it might look for a place to sleep. Usually you will be choosing methods that vary depending on the state. In this case, say there was only one method that varied depending on the state of the dog; what the dog’s looking for. The method signature might be: public void lookForSomething();. Now take this method signature and copy it (don’t erase it from the dog class).
  4. Now create a new hierarchy, either with an abstract base class or an interface, that declares (not defines) these methods — lookForSomething() — that you chose in step 3. This hierarchy will now be explicitly for use within your Dogs. If you have other animals that these states may apply to, you could use this hierarchy for them as well, but usually you will have a new hierarchy of states for each FSM that you have.
  5. Now, create subclasses within your State hierarchy that define each of the various states that your FSM will be using. In our example, you would create HungryState, TiredState, and SleepingState subclasses. Now each of these classes must define the abstract methods that were declared in the base class. You would write a definition in each subclass for the lookForSomething() method. In the HungryState, the method might tell the Dog to look for something to eat. In the TiredState, the method might tell the Dog to look for a place to sleep. In the SleepingState, the method might not do anything; you could just leave it blank. This is a viable option because as you know, if you’re sleeping you’re not going to look for something. Therefore, it is okay to leave the method definition blank in the SleepingState, or you might want to send output notifying the caller that the Dog is sleeping.
  6. You need to have an instance variable somewhere of the type of FSM that your states will be applied to. In our example, our abstract base class DogState would have a variable of type Dog. This is necessary for the various states so they have a Dog to change, otherwise they would just be definitions of methods that do something on their own, not change the way something acts. So, if you created your State hierarchy with an interface, you would have to add a variable of type Dog in each of the subclasses, but if you use an abstract class you could put that variable in the base class for every subclass to inherit.
  7. Now, within your FSM, you need to add some new member variables, one (or many) for each of the possible states, plus one for the current state. So in our Dog class, we would add four new variables of type State, and it would look something like this:
    • class Dog {
    • State hungryState;
    • State tiredState;
    • State sleepingState;
    • State currentState;
    • … }
  8. Now in the constructor of the Dog, you would create a new object of the various state subclasses, and assign those to the appropriate variables.
  9. Now, go back to your methods in the Dog class, in our case just the lookForSomething() method. Within this method, you just delegate the task of lookForSomething() to the currentState. The definition of the lookForSomething() in the Dog would look like: currentState.lookForSomething();. This will invoke the correct method definition depending on what state the Dog is in.
  10. When you make your checks on the Dogs hunger level and tired level, you would add an assignment to set the Dogs currentState = hungryState if its hunger level was low enough, or currentState = tiredState if it was tired enough.
  11. Now when lookForSomething() is called on the Dog, the task will be delegated to the currentState of the dog, and an appropriate execution of the method will occur. If currentState = tiredState, when lookForSomething() is called, the definition provided in the TiredState class will be executed.
Advertisements
Categories: Assignments Tags: ,
  1. No comments yet.
  1. No trackbacks yet.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: