Wednesday, August 25, 2010

PatternCraft – Strategy Pattern

PatternCraft is a series of video tutorials that use StarCraft references to teach Design Patterns.

This video is the first in the series and covers the Strategy Pattern. You can watch it in the player below or just download it here to watch however you'd like:

Visitor Pattern
Memento Pattern
Command Pattern
State Pattern

Source is here: http://github.com/johnlindquist/johnlindquist.com/tree/master/StategyPatternDemo/src/

37 comments:

  1. Nikos4:04 AM

    This is my favourite blog :)

    ReplyDelete
  2. Cool example, thanks a lot!

    One change I would have made to the StrategyPatternDemo class, is to apply the "program to the interface, not the implementation" principle:
    Instead of:
    private var viking:Viking;
    or
    private var raven:Raven;
    do:
    private var vehicle:Vehicle;
    and then in your constructor:
    vehicle = new Viking();
    or
    vehicle = new Raven();

    It's a small change of course, but it makes your code more flexible.

    ReplyDelete
  3. Just excellent. Thank you !

    ReplyDelete
  4. johnlindquist8:21 AM

    Thanks, you're my favorite commenter :)

    ReplyDelete
  5. johnlindquist8:21 AM

    Yup, I'm saving those discussions for the creational patterns videos. It's way too easy to get side-tracked on a tutorial even if you only barely mention something like that.

    ReplyDelete
  6. Excellent explanation john! But based on the video it's not clear why you would choose this pattern instead of using a static Move class with .fly() .walk() .swim() methods. And one benefit would be that you wouldn't be instantiating a new Move object for each movement.

    ReplyDelete
  7. seeing as how my knowledge of design patterns is relatively low besides the basics like mvc and singletons and my recent addiction to starcraft is stronger than ever makes this one of my favorite learning experiences OF ALL TIME :)

    ReplyDelete
  8. johnlindquist9:36 AM

    Personally, I think static methods should be reserved for code that never changes. Like Math.round() will never change, but something like Move.fly() could definitely changed based on your requirements. Also, it's good architecture practice to "program to an interface" so that your contracts/relationships between classes are locked in place. Believe it or not, it's actually a good thing that changing the interface would break everything. Think of an interface as a contract between you and your client. If you break the contract, all of your employees and all of their employees need to know they can't work together anymore.

    As for creating new Move objects each time, there's a Flyweight design pattern for that "problem", but I didn't want to make the video any more complex than it already was.

    ReplyDelete
  9. That's definitely true, the video is nicely focused this way. Looking forward to the next PatternCraft!

    ReplyDelete
  10. I love the name you decided on. Well done!

    ReplyDelete
  11. I recently discovered the value in the statement "Static methods are bad".. From the standpoint of unit-testable code this is significant.

    Of course its really annoying having to hand in a single instance to every class that needs a "Math" instance, but thats where DI IoC comes in :D

    ReplyDelete
  12. jacksondunstan2:35 PM

    Thanks for the video, it was a really nice presentation. @Lee Fernandes- As for having to create new movement behavior objects all the time, you can always cache ones you're not using anymore to eliminate the #1 problem with this: switching back and forth between a few behaviors really fast.

    ReplyDelete
  13. Darren5:41 PM

    Bravo John. Your videos are some of the finest tut's I've seen. Your efforts are much appreciated and your coding it inspirational.

    ReplyDelete
  14. @Lee Fernandes The easiest and quickest solution to the 'new' problem is creating a simple class like the following:
    package patterncraft.strategy
    {
    import patterncraft.strategy.*;
    public class MoveVehicleBehaviorTypes
    {
    public static const FLY:Fly = new Fly();
    public static const SWIM:Swim = new Swim();
    public static const TELEPORT:Teleport = new Teleport();
    public static const WALK:Walk = new Walk();
    }
    }

    Then within the other class you can type: raven.moveBehavior = MoveVehicleBehaviorTypes.FLY;

    ReplyDelete
  15. Thanks for sharing! I usually just use static methods for utility methods also. Last time I implemented an interface I began feeling constricted & duping too much unnecessary code. Though that might be a good thing as you mention debugging & stability = )

    ReplyDelete
  16. Looks good sir! I like the use of const. Depending on volume of move types you might want a method to check if instantiated & only instantiate on initial demand. new WarpcoreTechnology() new DrunkenCabDriver() new RedbullGivesYou() new TheRingCrawl() new Jumper() haha ok.

    ReplyDelete
  17. johnlindquist1:48 AM

    I'll cover some of the creational and structural patterns later to show some better solutions and why your example could cause trouble.

    ReplyDelete
  18. Thats so much easier to understand than any book I've bought so far :)

    ReplyDelete
  19. I'll be the person who goes off topic and asks about the IDE this time. =)

    Your videos have gotten me to try IntelliJ. I've gotten test projects up and running. However, each project shows up in its own window (or replaces the existing window). How did you get several projects to show up in one window in this video? Are they just "modules" within a single project? (I've noticed that IntelliJ uses the term "module" -- I assume it's different than a Flex module but I haven't quite figured out for myself what they are like, so any insights you have are appreciated.)

    Going back to the topic of the video, I enjoyed and appreciated the video and the concepts it taught, too.

    ReplyDelete
  20. Steve7:20 PM

    Thanks for this tutorial! I can't learn design patterns unless they're applied to real world problems, so this video was very refreshing. I hope you'll cover more design patterns soon.

    I found this site from someone linking to your Signals tutorial (which was also great!), and am now going through all your RobotLegs stuff, too. Keep up the great work.

    ReplyDelete
  21. johnlindquist1:05 AM

    Let me point you to the eclipse->IntelliJ migration FAQ:
    http://www.jetbrains.com/idea/documentation/mig...

    ReplyDelete
  22. Orlando11:04 AM

    This is great! Keep'em coming!

    ReplyDelete
  23. Hi John, hi guys,
    it's always amazing to see you coding John, it's the Ide or you nature? I'm wandering when we will see all this in Flash Builder? Maybe in FB 6.9?!

    ReplyDelete
  24. this video is amazing.

    ReplyDelete
  25. theFlash1:14 PM

    VERY cool man . much easier to grasp the concepts like this, I like how you are showing how to use a design pattern to solve a basic problem - and that you're using Starcraft 2 is just too good... hope to see more - take it easy

    ReplyDelete
  26. Watched a couple of your PatternCraft tutorials and have found them to be extremely elegant explanations for design patterns even though I'm not a starcraft player.

    ReplyDelete
  27. johnlindquist12:20 PM

    Thanks! I'm trying to keep a consistent frame of reference so people have visuals to associate with the patterns. Starcraft is just a great frame of reference :)

    ReplyDelete
  28. This is a great video tickling out the nuances of the Strategy design pattern. I've recommend it to our readers (http://www.as3dp.com) and I hope you continue making videos on the different design patterns. We're trying a "saturation" approach to design patterns, taking one from each of the three major categories and having several posts on each in the hopes that our readers can connect with them. You're was linked as the first to view when considering the Strategy design pattern.

    Kindest regards,
    Bill Sanders

    ReplyDelete
  29. johnlindquist7:34 AM

    Thanks Bill! I read your book a couple years back and I remember it being the best as3 design patterns book out there.

    I'm going to focus on one video per pattern starting with all the behavioral patterns.

    ReplyDelete
  30. Good coverage about the strategy pattern, however I wonder what would be the best for this case. Strategy Pattern or the State Pattern.

    I included a implementation of the State Machine of the ground an fly mode:

    [code]
    interface IStateMachine
    {
    function get Current():IState;
    function set Current(state:IState):void;

    function SetState(state:IState):void
    }

    interface IVehicleOperations
    {
    function Move():void
    }

    interface IState
    {
    function get Machine():IStateMachine;
    }

    class Vehicle implements IVehicleOperations, IStateMachine
    {
    private var _state:IState;

    public function get Current():IState { return this._state; }
    public function set Current(value:IState):void { this._state = value; }

    public function Vehicle()
    {
    //initial state
    this._state = new GroundState(this);
    }

    public function SetState(state:IState):void
    {
    this._state = state;
    }

    public function Move():void
    {
    this._state.Move();
    }
    }

    class FlyingState implements IVehicleOperations, IState
    {
    private var _machine:IStateMachine;

    public function get Machine():IStateMachine
    {
    return _machine;
    }

    public function FlyingState(machine:IStateMachine)
    {
    this._machine = machine;
    }

    public function Move()
    {
    trace('I am flying');
    }
    }

    class GroundState implements IVehicleOperations, IState
    {
    private var _machine:IStateMachine;

    public function get Machine():IStateMachine
    {
    return _machine;
    }

    public function GroundState(machine:IStateMachine)
    {
    this._machine = machine;
    }

    public function Move()
    {
    trace('I am riding');
    }
    }
    [/code]

    From what I've read from http://www.mail-archive.com/gang-of-4-patterns@cs.uiuc.edu/msg00222.html:

    "Also, in State, the dependencies are all tangled. States know about other States. They know how to transition to other States. They set the next State on the Context object. Sometimes the State base class knows about its subclasses. This is not the case in Strategy.

    Another difference is that Strategy does the algorithmic work, whereas, in State, a State object usually just calls back to the Context to do the work."

    Would a State Machine be a better case for this one?

    I would like to hear your opininon

    ReplyDelete
  31. Pierre8:39 AM

    Thanks ! I loved it !

    ReplyDelete
  32. Hi!
    I really like your videos. You keep it simple and easy to grasp. However, I would like to se an overview of what each pattern are supposed to do before jumping into changes in the code. I'm talking about how the code, functions and classes are connected. Both showing how people usually do and showing how your pattern is built and discussing the pre and cons of your system.

    ReplyDelete
  33. [...] PatternCraft tutorials: Mediator Pattern Visitor Pattern Command Pattern State Pattern Strategy Pattern var flashvars = { width: "720", height: "586", autostart: "false", repeat: "false", backcolor: [...]

    ReplyDelete
  34. [...] Other PatternCraft tutorials: Mediator Pattern Memento Pattern Command Pattern State Pattern Strategy Pattern [...]

    ReplyDelete
  35. Stoner4:25 PM

    Fantastic! I learned in 22 minutes something that I would last at least a whole morning to understand... Thanks a lot!

    ReplyDelete
  36. [...] already covered the state pattern and the strategy pattern, but many people find it difficult to distinguish between the two. I put this tutorial together to [...]

    ReplyDelete