COMMUNITY

Design pattern strategy

I’m not quite sure what you mean by “best method”, could you elaborate?

OK

I’m moving forward. My next chanllege is to create sperate Haxe files, and seperate Duck classes.
MallardDuck.hx

import Quack;
import FlyWithWings;
 
class MallardDuck extends Duck
{

	public function new() 
	{
		
	}

	var pMallard = new Duck();
	pMallard.quackBehavior = new Quack();
	pMallard.flyBehavior = new FlyWithWings();
	
	public override function Display()
	{
		trace("I'm a real Mallard duck");
	}
	
}

Main.hx

package;

import neko.Lib;
import MallardDuck;

class Main 
{
	var mallard = new MallardDuck();
	
	
	static function main() 
	{
		trace("hello world");
	}
	
}

I’m getting src/MallardDuck.hx:19: characters 2-10 : Expected }

But, the MallardDuck file is fine?

Any ideas?

You’re not allowed to put code directly into the body of a class (pMallard.quackBehavior = new Quack(); etc), it has to be inside of a function. You can only have fields inside of a class body (variables, properties and functions).

Another note: having a function named Display violates the usual naming conventions that are used in Haxe, where functions use camelCase. Capitalized / PascalCase function names like that are usually found in C# and sometimes C++. Similarly, it would be considered bad practice to add prefixes to identifier names (like the p in pMallard) in Haxe.

Thanks, Gama11, That helps. I’m now trying to understand abstract functions which seems to be different to c++ abstract:-

abstract DisplayResult()
	{
		inline public function new()
		{
		}
	}
  

I’m getting Expected } error?

Any suggestions?

Thanks.

Abstract types in Haxe actually have nothing to do with abstract classes in C++ / Java / C# etc, they’re a completely different concept. There is no equivalent of abstract classes in Haxe.

See also: https://stackoverflow.com/questions/30377305/is-there-a-way-to-declare-classes-and-methods-as-abstract-in-haxe

The syntax error is caused by the empty (), you need to provide any underlying type for an abstract type. However, a Haxe abstract is probably not what you want here at all. :slight_smile:

Thanks again, are they a list of haxe limitation compared to C++, OOP. So, I 'll know how best to modify the UML diagram for Haxe code. I’ve got it working for MallardDuck before is the source code. If you all can confirm it is behaving as a Strategy pattern.
Duck.hx

// Duck is abstract class
class Duck
{
	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;
	}

	// In the UML Display (DisplayResult) is an abstract function
	// Haxe do not support abstract (like c++)
	public function DisplayResult()
	{
	}
  
  public function performFly():Void
  {
	  flyBehavior.fly();
  }
  
   public function performQuack():Void
  {
	  quackBehavior.quack();
  }
  
  public function swim():Void
  {
	  trace("All ducks float, even decoys");
  }
}

QuackBeavior.hx


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

``
Quack.hx

class Quack implements QuackBehavior
{
	public function new()
	{
	}
	public function quack():Void
	{		trace("Quack");
	}
}

MallardDuck.hx

class MallardDuck extends Duck
{

	public  function new() 
	{
		super();
		quackBehavior = new Quack();
		flyBehavior = new FlyWithWings();
	}
	
	public override function DisplayResult()
	{
		trace("I'm a real Mallard duck");
	}
	
}

Main.hx

import neko.Lib;
import MallardDuck;

class Main 
{	
	static function main() 
	{
		var mallard = new MallardDuck();
		mallard.DisplayResult();
		mallard.performQuack();
		
		trace("hello world");
	}
	
}

So, in theory, it should now work for remaining classes:- :slight_smile:

Just a passing opinion here, but I really don’t like to see things like this being done using “function pointers.” (In other words, the object has, as a variable, a reference to the functionality that is to be called.) As a design principle, I consider this to be too fragile. I cannot “look at the source code and be certain what’s going to happen at runtime.” Prior runtime behavior – that is to say, “the bug that I am now trying to find!” – might have altered this.

Instead, I would want mallardDuck to – if at all possible – directly implement behaviors such as fly and quack, overriding as necessary the implementations in a Duck base class. I would want the ultimate behavior to be something that can be conclusively known to the compiler.

Obviously, this is a technical design decision and I am merely expressing my personal opinion and JM2CW experience. “Your mileage may vary.™”

Thanks for this.

I’m returning back to study design patterns, and take a close look at your comment.

Thanks again