My initial idea of having a “thrill ride” through a design pattern to help reveal its operation is turning out to be awkward in more ways than I envisioned. The initial tour is going to be through a State Design Pattern; so naturally I set it up using a State pattern. It wasn’t too long before I realized that it would be difficult to visit all of the participants without adding new states that would show visiting the Context and State interface. In other words, I needed VisitContext and VisitState state classes.
After some fumbling, I saw that much of the important work is done by the Client. It actually works like a composer, especially since the State design is a beautiful example of both composition and delegation. Each participant had some responsibility in the process that I wanted to reveal in the sequence in which it occurs. With the State design, this is especially challenging because the context changes with each state. So how does one go about making a tour of such a process?
What Varies?
Then it occurred to me that were I to spend time on setting up a tour of the State design pattern, why not create a reusable application that I could use on any pattern I wanted? Of course this brought me back to the most basic question of design pattern development—what varies? In other words what varies in a tour of a pattern? So I whipped out my Magic Table to look at the possible variations in a design pattern. Well, I knew that the patterns were going to vary, but what does that look like in the Magic Table? Here were some that stood out:
I’ll get to the decisions involved in deciding on the best design pattern for making my thrill ride through different design patterns in a bit, but first, I wanted to consider the initial animations, graphics and design. The embedded SWF shows what I have in mind. The “control panel” is made up of buttons representing the different states (The animation just goes from the Client to the Context but it gives an idea of the animation I’m considering. It only goes to one state and then this page has to be reloaded to start over.)
One of the least discussed relations in Design Patterns is where one participant creates an instance of another. Basically, the pattern calls for one class to instantiate another class. This relationship is indicated by a broken line with an arrowhead pointing to the class that has been instantiated. (The Participant Relations diagram above shows Class C instantiating (creates) Class F with the red broken line and arrow.) The creates relationship is found in only five design patterns:
An open triangle on a line from a child class to the parent class indicates the inheritance symbol in Design Pattern class diagrams. In the Participant Relations diagram above, you can see symbols for both single and multiple inheritance in red. Inheritance in design patterns is so common, pointing out which designs do not use inheritance is easier than listing all of the ones that do. Those pattens that have no inheritance in their design include:
So when thinking about inheritance, you can begin by thinking design patterns because most include some kind of inheritance in the relations between pattern participants.
But I thought they said…
You’re probably thinking that a key principle for design patterns is to favor object composition over class inheritance, and here we find that the Gang of Four is using inheritance in all but three of their design patterns. What’s up with that?
I wanted to move on from the original Aid Game, at least as far as the movement was concerned; so I fully fixed it up. With the new set of rules from the previous post of repairing the movement, I realized that if I didn’t generate fully operating movement states, we’d end up overly focusing on the wrong things. So, I set up a class (TimeMachine) to encapsulate the Timer object, and then the Mover class became the child of the TimeMachine using the different TimeMachine Timer properties. Because I instantiated a Timer object in each of the properties in the TimeMachine, I do not believe it is properly an Abstract class. However, like an Abstract class, it is not invoked directly, but rather through inheritance.
Playing the Game by the Rules: First Break the Rules
The nice thing about a State design pattern is that once the rules are established, you can build your algorithms and the different states invoke them according to the rules you’ve established. You can have a number of different algorithms within the State framework, and they should all work in accordance with the rules—no matter what the rules are or what algorithms you use to invoke them.
To see if the revised game follows the movement rules, try and break the rules. The main rule that you can attempt to break is the No reverse without stopping rule. So if you’re going right and you press the Left button, your helicopter should first stop and then you’d have to press the Left button a second time. Or you can reverse direction by pressing the Stop button and then press the opposite direction. Click the Play button to give it a whirl:
So go ahead and try to break the rules! If you can; then the design fails. If not, it succeeds. Once you’re finishing playing, download the latest code and see how the rules were applied.
In a recent post to illustrate the use of composition and delegation, I created a simple game using a State design Pattern—the Aid Game. A lot of people had lots of questions and suggestions for making it better and being one who thrives on improvement and change, I promised to have a post where we’d review it as a State design pattern and not a quick and dirty example of composition.
In this post I’d like to go over some key elements of a State design and to see if we can improve on the original Aid Game by better design of state classes. Also, I’m going to leave the final repairs up to you—I’ll provide some guidelines for improved states, and you can implement them. Also, I’ll provide a little helper class that is an example of continuous movement based on one from our book that Chandima used to illustrate MVC. (I simplified it from the original; so if you look at the MVC chapter—Chapter 12—, you’ll only see pieces of it.)
Why a State Design and What are the States?
To get started, we have to ask the same key question that we should ask for every design we do. Namely,
What varies?
In moving the helicopter around in the Aid Game, the main thing that varies is the state of flight. (Each of the different directions and a stopped state represents a variation in state.) Ergo, I selected the State Design Pattern.
In our simple State design, I used five different states:
Stop
Move Right
Move Left
Move Up
Move Down
Next, I’ll add some rules that were not in the first version:
Before reversing direction, you must first go to the Stop state.
If a current state is called, it cannot invoke itself.
Recent Comments