Show me the Strategy
Story about Strategy Design Pattern (Behavioural)
created by Vladimir Minkin
Photo by Maarten van den Heuvel
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.
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
Show me the Strategy
By Vladimir Cores Minkin
Show me the Strategy
Description for Strategy Pattern
- 552