Java Reference
In-Depth Information
Benefits and Drawbacks
Benefits and drawbacks include the following:
State partitions behavior based on state - This gives you a much clearer view of the behavior. When the object is
in a specific state, look at the corresponding State subclass. All the possible behavior from that state is included
there.
State offers structure and makes its intent clearer - The commonly used alternative to the State pattern is to use
constants, and to use a switch statement to determine the appropriate actions. This is a poor solution because it
creates duplication. A number of methods use almost exactly the same switch statement structure. If you want to
add a new state in such a system you have to change all the methods in the Context class by adding a new
element to each switch statement. This is both tedious and error-prone. By contrast, the same change in a system
that uses the State pattern is implemented simply by creating one new state implementation.
State transitions are explicit - When using constants for state, it is easy to confuse a state change with a variable
assignment because they are syntactically the same. States are now compartmentalized in objects, making it
much easier to recognize a state change.
State can be shared - If State subclasses contain only behavior and no instance variables, they have effectively
become Flyweights. (See “ Flyweight ” on page 183.) Any state they need can be passed to them by the Context .
This reduces the number of objects in the system.
The State pattern uses a large number of classes - The increased number of classes might be considered a
disadvantage. The State pattern creates at least one class for every possible state. But when you consider the
alternative (long switch statements in methods), it's clear that the large number of classes is an advantage,
because they present a much clearer view.
Pattern Variants
One of the challenges of the State pattern is determining who governs the state transitions. The choice between
the Context and the State subclasses was discussed previously. A third option is to look up the transitions in a
table structure, with a table for each state, which maps every possible input to a succeeding state [Car92]. This
converts the transition code into a table lookup operation.
The benefit is the regularity. To change the transition criteria, only the data in the table has to be changed instead
of the actual code. But the disadvantages are numerous:
Table lookups are often less efficient than a method call.
Putting the transition logic in a table makes the logic harder to understand quickly.
The main difference is that the State pattern is focused on modeling the behavior based on the state, whereas the
table approach focuses on the transitions between the different states.
A combination of these two approaches combines the dynamics of the table-driven model with the State pattern.
Store the transitions in a HashMap , but instead of having a table for each state, create a HashMap for every method
in the State interface. That's because the next state is most likely different for each method.
In the HashMap , use the old state as the key and the new state as the value. Adding a new State is very easy; add
the class and have the class change the appropriate HashMaps . This variant is also demonstrated in the Example
section for this pattern.
Related Patterns
Related patterns include the following:
Flyweight (page 183) - States can be shared using the Flyweight pattern.
Singleton (page 34) - Most States are Singletons, especially when they are Flyweights.
Search WWH ::




Custom Search