COMMUNITY

Design pattern strategy

(fm) #1

Hi
I’m learning about design pattern strategy. I’m in the process of writing a simple Haxe program using design pattern strategy. Are they any example Haxe source codes design pattern strategy?

(Dan Korostelev) #2

I think the simpliest example of a strategy “pattern” would be just a function passed to another one as a value:

// context
function think(strategy:()->String) {
  trace("I will " + strategy());
}

// strategies
var yellStrategy = function() return "yell";
var runStrategy = function() return "run";
var fightStrategy = function() return "fight";

// usage
think(yellStrategy);
think(runStrategy);
think(fightStrategy);

Of couse instead of a function type one could use an interface or a structure type, which is useful if your strategy consists of several methods.

(fm) #3

Great!!

Thanks for this, and for a very quick reply I’m using a simple interface.

Codes are based on Java codes from the book

Head First Design Patterns

I have two interfaces

interface FlyBehavior
{
public function fly():Void;

}

interface QuackBehavior
{
public function quack():Void;
}

I’m having problems implements both interfaces in the class Duck.

class Duck implements FlyBehavior implements QuackBehavior
{
var FlyBehavior flyBehavior;
//var QuackBehavior quackBehavior;

private function new() // Constructor
{
	
}

public function setFlyBehavior(fb:FlyBehavior):Void
{
	flyBehavior = fb;
}


public function setQuackBehavior(qb:QuackBehavior):Void 
{
	quackBehavior = qb;
}

abstract Display(Void)

{
inline public function new()
{

	}

}

public function performFly():Void
{
flyBehavior.fly();
}

public function performQuack():Void
{
quackBehavior.quack();
}

public function swim():Void
{
trace(“All ducks float, even decoys”);
}
}

(Dan Korostelev) #4

eww, your code formatting gone wrong, use triple backticks :slight_smile:

(fm) #5

Sorry about that late night :slight_smile:

interface FlyBehavior 
{
	public function fly():Void;
	
}
interface QuackBehavior 
{
	public function quack():Void;
}
class Duck implements FlyBehavior implements QuackBehavior
{
	var FlyBehavior flyBehavior;
	//var QuackBehavior quackBehavior;
	
	private function new() // Constructor
	{
		
	}
	
	public function setFlyBehavior(fb:FlyBehavior):Void
	{
		flyBehavior = fb;
	}
	
	
	public function setQuackBehavior(qb:QuackBehavior):Void 
	{
		quackBehavior = qb;
	}

	abstract Display(Void)
  {
	  inline public function new()
		{
			
		}
  }
  
  public function performFly():Void
  {
	  flyBehavior.fly();
  }
  
   public function performQuack():Void
  {
	  quackBehavior.quack();
  }
  
  public function swim():Void
  {
	  trace("All ducks float, even decoys");
  }
}
(Jens Fischer) #6

Also, you can edit posts. :wink:

(fm) #7

Im still learning :slight_smile:

(fm) #8

Update - I think I got both interfaces to implement into Duck.
But, getting the following errors:-
src/Main.hx:17: lines 17-54 : Field quack needed by QuackBehavior is missing
src/Main.hx:17: lines 17-54 : Field fly needed by FlyBehavior is missing

Line 17 is “class Duck implements FlyBehavior implements QuackBehavior”

Any suggestion?

interface FlyBehavior 
{
	public function fly():Void;
	
}

interface QuackBehavior 
{
	public function quack():Void;
}

class Duck implements FlyBehavior implements QuackBehavior
{
	var flyBehavior:FlyBehavior;
	var quackBehavior:QuackBehavior;
	
	private function new() // Constructor
	{
		
	}
	
	public function setFlyBehavior(fb:FlyBehavior):Void
	{
		flyBehavior = fb;
	}
	
	
	public function setQuackBehavior(qb:QuackBehavior):Void 
	{
		quackBehavior = qb;
	}


  
  public function performFly():Void
  {
	  flyBehavior.fly();
  }
  
   public function performQuack():Void
  {
	  quackBehavior.quack();
  }
  
  public function swim():Void
  {
	  trace("All ducks float, even decoys");
  }
}

(Valentin Lemière) #9

You need to add the fly and quack functions to your Duck class.

An interface lists the fields that needs to be added.

(Dan Korostelev) #10

I’m not sure why are you implementing your strategy interfaces in your Duck class, which IIUC is supposed to be the “context” here? Is it so you can use Duck as a strategy itself? Is this intended?

(fm) #11

Thanks for replying.

I’ll upload the UML jpeg which may explain what I’m trying to do. Duck as a strategy itself.

Hope this help.

(Valentin Lemière) #12

The UML looks fine. But since in it Duck doesn’t have a link to either QuackBahavior or FlyBehavior you should not make it implement them.

You need to make your FakeQuack/… implement QuackBahavior, FlyNoWay/… implement FlyBehavior, and DecoyDuck/… extend Duck.

(fm) #13

Thanks again.

Sorry I’ve uploaded the wrong jpeg

This image shows the UML in more detail. Both interfaces are linked to Duck via aggregation relationship.

My next question is howto represent aggregation in Haxe code?

(Valentin Lemière) #14

There’s nothing to do for aggregation, both classes are independent, but one use the other.

And here since you store the two behavior in the duck that’d be composition.

And there’s nothing special about haxe that’d make it any difference than c# or java :wink: so you can easily use resources you find that use those languages.

(fm) #15

:slight_smile: Thanks ibilon & nadako. I think I understand what is going on and the reason behind the errors I was getting. I’ll continue tweaking the code and update you of any problems.
Thanks

(Mark) #16

I would implement it like this. I didn’t use interfaces here, but if you want you could do that too.

Check http://try-haxe.mrcdk.com/#89869

class Test {
    static function main() {
        var duck1 = new Duck("Bert");
        duck1.flyBehavior = new FlyRocketPowered();
        duck1.quackBehavior = new FakeQuack();
        duck1.fly();
        duck1.quack();
      
        var duck2 = new Duck("Ernie");
        duck2.flyBehavior = new FlyNoWay();
        duck2.quackBehavior = new Squeak();
        duck2.fly();
        duck2.quack();
    }
}

class Duck {
    public var flyBehavior:FlyBehavior;
    public var quackBehavior:QuackBehavior;
  	public var name:String;
    public function new(name:String) {
      this.name = name;
      trace('Hi, I am a new duck called $name');
    }
    public inline function fly() {
      trace('$name is going to fly:');
      flyBehavior.fly();
    }
  
    public inline function quack() {
      trace('$name is going to quack:');
      quackBehavior.quack();
    }
    public inline function swim() trace("I cannot swim");
}

typedef QuackBehavior = {
    function quack():Void;
}
class Squeak {
    public function new(){}
    public function quack():Void {
        trace(" - Squeak!!!");
    }
}
class MuteQuack {
    public function new(){}
    public function quack():Void {
        trace(" - ..!!!");
    }
}
class FakeQuack {
    public function new(){}
    public function quack():Void {
        trace(" - Faking quack!!!");
    }
}
    
typedef FlyBehavior = {
    function fly():Void;
}
class FlyNoWay {
    public function new(){}
    public function fly() {
        trace(" - Im flying, no way!");
    }
}
class FlyRocketPowered {
    public function new(){}
    public function fly() {
        trace(" - Dude I'm flying on a rocket!");
    }
}
class FlyWithWings {
    public function new(){}
    public function fly() {
        trace(" - Wat. I fly with wings!");
    }
}
> Hi, I am a new duck called Bert  
> Bert is going to fly:  
>  Dude I'm flying on a rocket!  
> Bert is going to quack:  
> - Faking quack!!!  
> Hi, I am a new duck called Ernie  
> Ernie is going to fly:  
> - Im flying, no way!  
> Ernie is going to quack:  
> - Squeak!!!  

The nice thing about the typedefs here is that you can create behaviors on the fly too, (eg. doesn’t have to be classes that implement an interface). But in the end depends on complete structure.

var duck3 = new Duck("Annie");
duck3.flyBehavior = { fly:function() trace(" - I'm flying like real bird") };
duck3.quackBehavior = { quack: function() trace(" - I'm quack like a queen!") };
duck3.fly();
duck3.quack();
(fm) #17

Wow!! mark.knol you have written this in few minutes. I wish I can code that fast.

This followers the original java/c++ code layout. I was reading about the Haxe typedef. I can see how it can be use in design patterns. I’ll studdy the code in more details and experiment with/without interface.

Thanks again.

(Mark) #18

Hope it helps getting you forward, good luck!

(fm) #19

I’m using HaxeDevelop to develp Haxe Code. It does have an option to single step through the code. Any ideas on the best method to single step through code?

(fm) #20

Same here. Once I know the basic of Haxe I should be able to use any design patterns. :slight_smile: I hope.

1 Like