
Helper Class is Helped
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.
Revising the Mover Class
To make it easier, the Mover class was revised so that the Timer was a property of a parent class (TimeMachine) that the Mover could use. This would provide a single source for the properties that could be inherited and used by the Mover to start and stop specific Timer instances used to move the helicopter.
1 2 3 4 5 6 7 8 9 10 11 12 13 | package { //Sort of an Abstract class //(But not really!) import flash.utils.Timer; public class TimeMachine { protected var timeRight:Timer=new Timer(5); protected var timeLeft:Timer=new Timer(5); protected var timeDown:Timer=new Timer(5); protected var timeUp:Timer=new Timer(5); } } |
All the TimeMachine does is create some properties, and even though it looks like an abstract class or interface, the properties are all instantiated and the Timer is set with a value. (Okay, so it’s concrete.)
Now that the Mover class has some inherited properties that are locked and loaded, it can focus on some simple algorithms to move the helicopter, as you can see in the following listing:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | package { import flash.events.TimerEvent; import flash.display.Sprite; public class Mover extends TimeMachine { private var sp:Sprite; //Go to the right public function goRight(sp:Sprite):void { timeUp.stop(); timeDown.stop(); this.sp=sp; timeRight.addEventListener("timer",doRight); timeRight.start(); } private function doRight(e:TimerEvent):void { sp.x++; } //Go to the left public function goLeft(sp:Sprite):void { timeUp.stop(); timeDown.stop(); this.sp=sp; timeLeft.addEventListener("timer",doLeft); timeLeft.start(); } private function doLeft(e:TimerEvent):void { sp.x--; } //Go up public function goUp(sp:Sprite):void { timeRight.stop(); timeLeft.stop(); this.sp=sp; timeUp.addEventListener("timer",doUp); timeUp.start(); } private function doUp(e:TimerEvent):void { sp.y--; } //Go down public function goDown(sp:Sprite):void { timeRight.stop(); timeLeft.stop(); this.sp=sp; timeDown.addEventListener("timer",doDown); timeDown.start(); } private function doDown(e:TimerEvent):void { sp.y++; } //Stop everything public function goStop(sp:Sprite):void { timeRight.stop(); timeLeft.stop(); timeUp.stop(); timeDown.stop(); } } } |
With its new set of properties, the Mover class can more easily keep track of which timers are running and which are stopped. Also, it can follow the rules laid out for movement and minimize unnecessarily stopping timers for a given state. For example, in the MoveDown state, the helicopter can not go directly to the MoveUp state. So the goDown() method does not have to include timeUp.stop() because that timer has already been stopped because it had to go to the Stop state first (which invokes the goStop() method in the Mover class) resulting in all timer instances to stop.
Walking through a Change of State
The changes made following a change of state may help you see how everything works together. So we’ll begin in the client with a Right button press and follow it through to where the helicopter is moved or stopped. (Keep in mind that the default state is Stop.)
//Client–request right movement from Stop state
private function doRight(e:MouseEvent):void
{
//contextNow is Context instance
contextNow.rightMove();
}
———–
//Context
public function rightMove():void
{
//stateNow is a State instance
stateNow.doMoveRight();
}
———–
//State > Stop
//context = Context instance
//context.mover = Mover object that
//is a property of the Context class
//context.chopper = Helicopter instance that
//is property of the Context class
public function doMoveRight():void
{
context.mover.goRight(context.chopper);
context.setState(context.getRight());
}
———–
//Mover class
public function goRight(sp:Sprite):void
{
timeUp.stop();
timeDown.stop();
this.sp=sp;
timeRight.addEventListener(”timer”,doRight);
timeRight.start();
}
———–
private function doRight(e:TimerEvent):void
{
sp.x++;
}
While that process is going on, a new State is set and held in the Context class. It is now ready for the next move—whatever it may be.
Bring on the Algorithms, but Don’t Forget this Stated as an Aggregation!
I know there are a lot of algorithm whizzes out there, and please feel free to provide algorithms that you think are more elegant, smarter or just plain better than what I cobbled together. However, please keep in mind that this discussion began because I was hoping to show how aggregation works in composition.
Also, why not add more states? You could add states to pick up and drop off aid supplies with the helicopter, for example. Or you could have states where a friendly Martian flying saucers help out in the first Intergalactic Aid effort!

The New Aid Game: The Machine Moves! by William B. Sanders, unless otherwise expressly stated, is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.


Bill Sanders
Hi Bill,
When I saw your first version of the Mover class I devised another one on my own. It’s much simpler than yours and based on Chandima’s one.
I have only a timer which I instantiate in the client and pass it to the context class as a parameter in a startGame function.
Here it goes:
The decreaseXSpeed and decreaseYSpeed let me get pure vertical or horizontal movements. This, of course, before the “not calling itself” rule.
I am preparing a new AidGame following the rules you gave.
However, I have a perfectly running one following the GoF implementation of the State pattern I mentioned in one of my posts. You can pick up aid(two different kinds)and drop it on the blocks(provided it is the class they expect/need)
I have tried to follow all the OOP principles and so I use several patterns and a lot of classes. It includes a Transporter class and two TransportState classes(loaded and empty), a Freight superclass for the Aid subtypes, and an Abstract Factory pattern.
As soon as I can I’ll implement the original State pattern (without using a superclass State).
Thank you again
Curro
Hi Curro,
What does the IMover interface look like? The only thing I borrowed from Chandima’s was the timer concept in the x/y increment/decrement; so it was actually much simpler than what Chandima had done with a lot less functionality.
Anyway, I appreciate seeing your Mover, but I’m not sure how it’s tied in with the State design. Does the Client call the Mover class directly or are the parameters passed through the Context or State classes? Let me know when you get the whole thing working as a State machine.
Thanks,
Bill
Bill,
the IMover class looks like this:
Everything goes through the Context class. The Client calls Context.startGame(t:Timer).
The State class looks like this:
The State subclasses need only override some of the behaviours. This is the Stop state, which has the most functionality:
The other States just override the method associated with them. For example, the MoveRight State:
I see you have merged decreaseXSpeed and decreaseYSpeed into a single function in the Mover class. That way it won’t work as expected.
Although I use a different State pattern implementation, I follow the rules and no State calls itself.
Thank you
Curro
Hi Curro,
I must have messed up the decreaseXSpeed and decreaseYSpeed when I formatted them. Please send me the original code and I’ll fix it for you.
In my view you have a fatal mistake in your State classes—they have conditional statements. One of the characteristics of the State and Strategy design patterns is that they have no conditional statements. The lack of conditional statements means that the code is easier to update because you have no such statements to unravel for newly added code. Of course your program works, but it is not a true State design pattern.
This is not to say that some examples of State design patterns do not have conditional statements—I have seen several. (In both Judith Bishop’s book and the Freemans’ Head First book you find the use of conditional statements in a State design.) The Head First book begins using conditional statements and then shows how your design can run into trouble by doing so (pp. 389-392.) Once they finish the example, the conditional statements are removed with the exception of some helper methods.
Your State class works something like an Abstract class, and with the State design you should be able to use a simple Interface as shown in the original example. By getting tangled up in algorithms, you lose the whole sense of a State pattern, and that was what I was trying to avoid.
Take another look at the final design I provided (click the Download button in this post) and you’ll see that no conditional statements are in the entire program—including the helper class. Everything moves crisply from one state to the next.
Kindest regards,
Bill
Hi Bill,
Thank you for pointing out the flaws in my code. I didn’t like it myself having conditional statements in the State pattern.
I guess I have to add two or three new states: OnAeroport,OnBlock and onRefusing Block, for example. But how do I check that chopper is on the airport or on one of the blocks without conditional statements? Bear in mind that in my implementation the chopper picks up and delivers aid depending on where it is. I guess I’ll have to add some event listeners to the State classes so that they know where they are.
On the other hand I have read about the ’stinkin singletons’ again and it’s clear that they break the SRP and bring some other evil into the design.
So I’ll stick to the original AidGame State pattern and find a solution to the conditional statements for the delivering and picking up processes.
I’ll place the ‘whole enchilada’ for downloading when it’s ready.
Thank you again,
Curro
Hi Curro,
Why not take the solution offered in this post as a starting point to see how the Context and States are set up? Then, once you have your states working (even with trace() statements to get started) add the necessary algorithms.
I am delighted that you are making it a real game with picking up and dropping off the “aid!”
Kindest regards,
Bill
Hi Bill,
I did take the solution offered and coded several AidGame versions with picking and dropping following your implementation of the State pattern. It’s only because I like to experiment and learn that I did another version following the GoF implementation. I liked it because it let me code less to get the same results.
I have now done a new version using the original State pattern(it didn’t take so long after all). I only had to revert to State as an interface (no Abstract Class) and do some other modifications.
You can effectively pick up to kinds of aid (food or med) and drop them on the blocks… if they want (some blocks accept med aid, and some others accept food aid)
I haven’t solved the no conditionals problem
but I think that there MUST be a conditional statement, if not in the State classes ,anywhere else (after all I have to use Sprite.hitTestObject which is boolean)
I include a link to the whole thing. It’s in my school website (www.iescorneliobalbo.es)
Again, thank you for your time, enjoy the game and if you can, please, point out any flaws you see.
Curro
AidGame pick and drop
Hi Bill,
I’ve re-read the chapter on the State pattern in the HeadFirst book
The conditional statements they eliminate belong to a state machine based precisely on conditional statements. But the conditional statement they do use in the SoldOut class (p.405) makes total sense. How else or where else can you check if the machine is empty?
After reading your comment above I tried to workaround the conditional statement. I devised three more states but in the end I had to check location. Anyway it’s also easy to take the conditionals out of the State classes: you place them in a function in the Context and call it from the State.
An important part of programming involves checking conditions; it’s better to avoid using conditional statements but in each program there are a few that are unavoidable.
I’ve come to the coclusion that this is the case in my Stop class.
Another thing Bill, couldn’t you set a problem specification on any area (a game, a quizz, a video player, etc.) and discuss here how to do it(what patterns to apply to the problem and how to use them)? We will go into how use patterns rather than in how they are implemented.
Thanks once more
Regards
Curro
Hi Curro,
I suppose that some conditional statements may be inevitable with certain implementations of the State design, but the reason I avoid them is for updates. The more conditional statements in a State design, the more likely you are to run into problems when you add or change a new element to your program.
Here’s my hunch. We all learn “tight programming” in the sense that we’re supposed to reduce redundant or duplicate code. However, we also learn “loose programming” in the sense that participants in a design pattern are loosely coupled. A nice switch statement can tighten things up by streamlining branches. That same switch (or other conditional), though, can also introduce branches that may not work when elements change.
The beauty of the State design is that each state provides its relationship to each other state. As states change, there’s no reason to use conditionals because each state defines what happens when a trigger changes states from any given state to any other state.
What the Freemans do with the State pattern in Head First Design Patterns is to begin by showing the problems that crop up when you have several conditionals; and so they take them out. The “helper” method that they stick in has a conditional (as I mentioned), but like a “helper” class, it’s really not part of the design per se. It’s a ‘helper.’ (Maybe it’s like a pimple on a beauty queen.)
Anyway, some patterns do have conditionals, such as the Chain of Responsibility (CoR), and in that pattern, you have to be aware that when you make updates, you have to take into account changes in the conditional branches if you add new responsibility handlers. Like GoF, we use a switch statement in our CoR examples because it is a core part of that design pattern.
Your last request for looking at a problem specification and then coming up with the design pattern to best deal with it begins with the Magic Table and working from there. Throughout this blog, Chandima and I have lots of examples that deal with different kinds of problems. Given the diverse interests of our readers, we have to use fairly general applications that lots of different readers can use.
Perhaps we can take an example problem requested by one of our readers, and if it’s general enough to have global application, we can work through the steps of figuring out which design pattern would be most applicable. Got any ideas?
Kindest regards,
Bill
Hi Bill,
I don’t like having conditional statements in a State pattern, since, as I have learnt here,one of the purposes of a State pattern is to avoid conditional statements.
However, in the HeadFirst book they use a conditional statement in a State class(look at SoldState.dispense() function) not in a helper class. It is a very simple conditional statement and makes sense.
Even so, I don’t like having conditional statements in a State class and I have now added three new states and taken the conditional statements to a function in the Context class which decides which of the new states(OnAirport, OnAcceptingBlock, OnRefusingBlock or Stop) to set, based on the chopper location.
However, I do use conditional statements in TransportState(an aggregate to Transport(an aggregate to Context))and these are unavoidable.
Again, thank you for your help and comments.
Curro
Hi Curro,
You’re right. I was referring to the helper method on pg. 403 (releaseBall) and part of the disperse method (pg. 405) is a conditional statement . It doesn’t look like either one would get in the way of new elements or changes. I still don’t like it, especially since the releaseBall() helper method is invoked in the disperse() method. Double conditionals…shudder.
Kindest regards,
Bill
Hi Bill,
I think the Freemans did that in a hurry. They don’t need the releaseBall method at all!
We can check count in SoldState, decrease it inside dispense() conditional statement and set either HasNoQuarterState or SoldOutState. Then, in SoldOutState we modify ejectQuarter so that it ejects the quarter and we don’t get an angry customer!
This way it works with only a conditional, though we can also put the conditional statement in the GumballMachine class and set either soldOut or hasNoQuarter from there!
Regards
Curro
Bill,
Not so good. We also need to set hasNoQuarter after ejecting the quarter in SoldOut.If we don’t, we’ll be giving away our quarters!
Regards
Curro
Hi Bill,
In answer to your request for ideas (
February 5, 2010 at 2:26 am), I think this little game of ours is a gold mine.
It’s true an aid game to take aid to needing blocks is not general, but it poses general problems like how to move an object, make an object transport one type or another of packet to some destination, how to view the results, how the classes needed could be reusable for other type of application … and so on. On the way we could discuss all the principles: LSP, SRP, DIP, OCP…
Well, hope you like the idea.
Thanks again
Curro
Hi Curro,
I agree and welcome new ideas and input. Right now I’m working on a new post using the Aid Game State design for a animated tour of the State design. It’s like a ride at a theme park—but instead of Space Mountain it’s Inside the State Machine
Cheers,
Bill
Hi Bill,
That sounds great!
Looking forward to seeing it.
Curro
its easy to break the rule for reverse, simply go left, up/down, right (there is no stop involve)
I agree and welcome new ideas and input. Right now I’m working on a new post using the Aid Game State design for a animated tour of the State design. It’s like a ride at a theme park—but instead of Space Mountain it’s Inside the State Machine
is this posted up? im interested.
here is a thought for everyone who is reading, patterns in design pattern help you to solve problems, you do not need to follow exactly. you don’t force your problem to fit into the pattern. For the if-else thingy, use them when you need for parts that does not vary, parts that varies means lots of updates happening in that part, you should work on another solution to prevent that, as the saying goes “open for extendability, closed for changes”.
By the way, what are those fancy short terms?
LSP, SRP, DIP, OCP…???
Hello Ayu,
#1. That’s not breaking the rules. It follows them by turning left/right before going up/down from the opposite direction.
#2. It’s difficult, and I want your help. Over the weekend (or maybe later today), I’m putting up the work so far of the “ride” and I’m looking for useful assistance and advice.
#3. Where did you get those terms?
Kindest regards,
Bill
Hi Bill and Ayu,
#3. Ayu refers to my last post, where I mention those “fancy short terms”
SRP: Single Responsibility Principle
LSP: Liskov Substitution Principle
DIP: Dependency Inversion Principle
OCP: Open-Closed Principle
Regards,
Curro
Hi Curro & Ayu,
First of all, Curro; thank you for clearing that up. (You’re the man!)
Second, Ayu: Those principles are key to understanding both OOP and Design patterns. Take a look at the Principles for OOP/DP we have discussed.
Kindest regards,
Bill
what is the point of having stop state being called after every moveRight/left/down/up?
Hi Ayu,
The point is the law of physics. To go in an opposite direction; there must be a stop as directions are reversed. However, if you don’t like that, it’s easy to change the code (which is really the point of Design Patterns.) So, why not just change the code in the concrete states to allow reverse direction without a stop state? If you want to change the rules; go ahead. In doing so, you will see how easy it is to do.
Take care,
Bill
i did not really like the solution you propose by using TimeMachine (many redundant functions), the simpler way is to combine the TimeMachine and Mover into Context, and use if-else.
Making unnecessary classes such as these makes it more complicated.
If you are strongly anti if-else for this tutorial, fill the implementation in the state itself. Use abstract class with a protected timer, to be inherited by the sub-states (move/left/right/up) similarly to how it was done by Curro.
Ayu,
I don’t think you understand what the State design is doing or attempting to accomplish. Rather than taking my word for it, look at pp 305-313 where Gamma, et al discuss it.
You’re still focusing on all the wrong elements. If you want to change the Context as you envision it, you’ll no longer have a State design but something else. The if-then-else structure is in a Chain of Responsibility design. Take a look at it and contrast it with the State design.
Bill
I completely understand how State Pattern works, I have read many State Pattern examples including Head First and Gamma. The point I am making is don’t force a problem into a pattern, let it come naturally. Design Pattern is there to help, you don’t need to follow completely, modify the pattern according to your needs.
Anyways, the example that you place in this post should be changed if you wish to stay on the real State Pattern. The movement done by the timer is place within the States itself without the need of additional class (TimeMachine and Mover) else it would be just the same by having it as if-else in the Context class.
Ayu,
No problem is forced into a pattern. I have no idea why you insist it is. With the focus you put on issues that seem to be primarily of interest to you, we keep getting off-point. If your focus were on the issues of re-use instead of some obsessive minutiae, I think we’d all move on more smoothly.
I really don’t care if you want to put in your if-elses. Go ahead. I hope you’re happy with them.
Goodbye,
Bill
You still do not understand the point I am trying to convey here.
Your method of mover and time machine is if-else
but you complicate it with many unnecessary functions and timers which is redundant. Also having these 2 will make no purpose of having all those many states in the first place.
Being as state pattern, the algorithm specific to a certain state, should be place in the state itself. Simple as that.
Solution:
1. Remove TimeMachine.as and Mover.as all together
- The algorithm is placed inside sub-states (up/down/left/right)
2. The state (interface) is converted into “abstract class”
- Default definitions is place inside the state
- The sub-state will override functions that it needs.
- The state contains a timer for the state to inherit, or you could have 1 static timer)
3. The context/controller will have a static instance to itself
- The substate will hold this as reference in its class when it needs to use the context/controller for its sp (the sprite or the helicopter sprite)
4. If I were to create a 360 degree movement, I will throw it out all together, and have 2 states, MoveState and StopState.
Ayu,
You continue to ramble on about algorithms you think are important and deflect from the focus of design patterns. Try and think about relationships between participants.
Bill
I half agree with this post:
In my view you have a fatal mistake in your State classes—they have conditional statements. One of the characteristics of the State and Strategy design patterns is that they have no conditional statements. The lack of conditional statements means that the code is easier to update because you have no such statements to unravel for newly added code. Of course your program works, but it is not a true State design pattern.
It will be more appropriate to say that if-else (conditional statements) should not be use to determine which state it should choose first before it does the algorithm.
But if-else can be use to check the condition of the chopper/helicopter and its surrounding, for instance fuel, item to be picked on ground (if there is pick it, else nothing to pick).
If you have read the Head First Design Pattern, the example they gave was a gumball, before the WinnerState gives 2 gumballs, it checks how many balls are left in the first place). If there aren’t any gumballs left (the state checks the context/controller for the amount of gumballs), then change into SoldOut State.
Another William B. Sanders post that I half agree:
Quote:
I suppose that some conditional statements may be inevitable with certain implementations of the State design, but the reason I avoid them is for updates. The more conditional statements in a State design, the more likely you are to run into problems when you add or change a new element to your program.
You don’t avoid using if-else, use it when you need it. If the if-else applies on one single responsibility, there is no harm in using it.
here is a simple example, when a chopper/helicopter picks up a weapon, the chopper would enable that specific weapon.
If the weapon is a machinegun, then enable machine gun. If the weapon is a rocket, enabled rocket launcher or if its already enabled, upgrade rocket launcher.
You continue to ramble on about algorithms you think are important and deflect from the focus of design patterns. Try and think about relationships between participants.
Do you have post on relationship between participants?
I am discussing on the State pattern, not rambling. Before you comment something like this, take some time and analyze on how I reconstruct your code.
Dear Ayu,
Forgive my impatience. Let me try and outline what we’re trying to do and how we view problem-solving in coding.
I hope that will help in fine-tuning an understanding of what we’re trying to do on this blog.
Kindest regards,
Bill
thanks, i understand why you code in that structure now :)
Hi Bill,
I am an AS developer from Germany. I have your book right next to the ‘Elements of reusable Object-Oriented Software’. :-)
At this point, even a big hello to the illustrative examples of the ‘State Pattern’ in your book.
And I ask you to excuse my weak English.
Currently I’m working on a ‘Layout Editor’ in AS3. These I have already been developed in AS2.
That was in 2006 – since then I am responsible for the software
and I think just about every mistake I made that one can make when programming a larger project.
The application has been extended and expanded, which meant that any error in the planning has taken its revenge.
Through your book, I get a better understanding for the cooperation of classes.
It is also extremely interesting and instructive to follow these contributions.
Back to the ‘State-Pattern’ – in the book “Elements of reusable Object-Oriented Software ‘on page 313 there is an example/diagram of a’ State-Pattern’ for a ‘Drawing Tool’ that I wanted to implement in this type.
Initially it was all about the selection of objects and their processing. For selection, I had developed a strategy.
After I read page 313 again, it was clear that here a ’state-Pattern’ offers.
However, my implementation is much closer to your implementation than the one of the GoF.
But I have found a good reason to use an abstract class.
To me it makes sense because with increasing number of tools there is always a function less for all states.
I have a public method ‘initialize’ and a protected method ‘removeListener’.
When a new tool is selected, the old tool can first remove all the listeners and then invoke ‘change tool’ in the context.
The context changes the tool and calls ‘initialize’ on the new tool – works great.
A tool is only created when needed, and is instantiated only once
which reminds me a bit of Flyweights…
If one looks exactly once, ‘Desing Patterns’ are everywhere in programming.
With best regards!
Jey
Hi Jey,
It sounds like you’re really doing a lot with design patterns. Like me, you’re also reading (and re-reading) Design Patterns: Elements of reusable Object-Oriented Software and I’ll probably have to do that always!
The issue of Abstract classes (and methods) in ActionScript 3.0 is important, and I agree with you that there are plenty of uses for it. I certainly hope that in the next version of ActionScript that they include them in the structure.
I’ve been doing a lot with PHP and while it is a weakly typed language, it does have Abstract classes and methods. They are quite handy at times!
Kindest regards,
Bill