Show me the Strategy

Story about Strategy Design Pattern (Behavioural)
created by Vladimir Minkin

Inheritance

Inheritance is a mechanism in which one object acquires all the properties and behaviors of parent object.

Vehicle

go()

abstract

RacingCar

@Override go()

Helicopter

Override go()

CityCar

Subtyping establishes an is-a relationship

beep()
Override beep()

Apache

Override go()

Jet

Override go()
Override beep()

Limits OOP?

Overuse of Inheritance. ​To many objects that needs to be maintainable​ with small changes in each.
Hard for runtime changes. 

 

"Encapsulate What Varies"

 

You can extend or alter them without affecting the rest of your code

UNITS MOVE - Inheritance Problem

Algorithms

Programming to Interface.Take code that varies and extract it to Algorithm objects.

Vehicle

Algorithm variable
Algorithm object 1
Algorithm object 2
Algorithm object 3
Algorithm object 4

Composition over Inheritance

polymorphic behavior

Strategy

Defines a "family" of algorithms, encapsulates them, and makes them interchangeable with an Interface. 

Client don't need to know details of how the behaviors implemented. 

An algorithm can be selected and exchanged at run-time.

 

Composition implements a has-a relationship

 

Example

public interface IMovable {
    void move(Vector2 position);
}

public class AviationMoveAlgorithm : MonoBehaviour, IMovable
{   
    public void move(Vector2 position)
    {
        this.transform.position = position;
        Debug.Log(string.Format("> Move Aviation : is moving by flying"));  
    }
}

public class InfantryMoveAlgorithm : MonoBehaviour, IMovable
{
    public void move(Vector2 position)
    {
        float distance = Vector3.Distance(transform.position, new Vector3(position.x, position.y));
        float time = distance / _speed;

        Debug.Log(string.Format("> Move Infantry : is moving by going : " + time));
        ...
    }
}

public class JumpMoveAlgorithm : MonoBehaviour, IMovable
{
    ...
    public void move(Vector2 position)
    {
        _path.Enqueue(position);
        if (isTweenInAvailable) {
            MoveToDestination();
        } 
        Debug.Log(string.Format("Terran Infantry : is moving by jumping" ));
    }
}
- Extract Interface
- Implements Algorithms

STEP 1

public abstract class Unit : MonoBehaviour
{
    static public Type getTypeForMoveAlgorithm(MoveAlgorithm input)
    {
        switch (input) {
            default:
            case MoveAlgorithm.Null: 		return typeof(NullMoveAlgorithm);
            case Unit.MoveAlgorithm.Aviation: 	return typeof(AviationMoveAlgorithm);
            case Unit.MoveAlgorithm.Jump: 	return typeof(JumpMoveAlgorithm);
            case Unit.MoveAlgorithm.Infantry: 	return typeof(InfantryMoveAlgorithm);
            case Unit.MoveAlgorithm.Wiggle: 	return typeof(WiggleMoveAlgorithm);
        }
    }

    public enum MoveAlgorithm {
        Null,
        Aviation,
        Infantry,
        Jump,
        Wiggle
    };

    private IMovable _moveAlgorithm = new NullMoveAlgorithm();

    virtual public void move(Vector2 position) { _moveAlgorithm.move(position); }

    public MoveAlgorithm GetMoveAlgorithm() { return _moveAlgorithmEnum; }

    public void SetMoveAlgorithm(MoveAlgorithm value)
    {
	_moveAlgorithm = (IMovable)this.gameObject.AddComponent(getTypeForMoveAlgorithm(value));
        Debug.Log("> Unit -> SetMoveAlgorithm: _moveAlgorithm " + _moveAlgorithm);
    }
}
- Abstract class

STEP 2

public class Battlecruiser : Unit 
{
    void Start () 
    {
        Name = "Battlecruiser";
	SetMoveAlgorithm(Unit.MoveAlgorithm.Aviation);
    }
}

public class Goliath : Unit 
{
    void Start () 
    {
        Name = "Goliath";
        SetMoveAlgorithm(Unit.MoveAlgorithm.Jump);
    }
}

public class Marine : Unit 
{
    void Start () 
    {
        Name = "Marine";
	SetMoveAlgorithm(Unit.MoveAlgorithm.Infantry);
    }
}

public class Medik : Unit 
{
    void Start () 
    {
        Name = "Medik";
        SetMoveAlgorithm(MoveAlgorithm.Null);
    }
}
- Concrete classes

STEP 3

Made with Slides.com