minte9
LearnRemember



Strategy pattern

Encapsulate different related algorithms. The client that instantiate an algorithm have no knowledge of the implementation.
  
abstract class Animal
{
    public $flyBehavior;
}

interface Fly
{
    public function fly();
}

class FlyBehavior implements Fly
{
    // @Override
    public function fly()
    {
        return "It flies";
    }
}

class NonFlyBehavior implements Fly
{
    // @Override
    public function fly()
    {
        return "Can't fly";
    }
}

class Dog extends Animal
{
    public function __construct()
    {
        // This is call 'composition'
        // Instead of inheritance ...
        // the class is composed with different objects
        
        $this->flyBehavior = new NonFlyBehavior(); // Look Here
    }
}

class Bird extends Animal
{
    public function __construct()
    {
        $this->flyBehavior = new FlyBehavior();
    }
}

$dog = new Dog();
echo "Dog: " . $dog->flyBehavior->fly(); // Dog: Can't fly

$bird = new Bird();
echo "Bird: " . $bird->flyBehavior->fly(); // Bird: It flies

Runtime

Another great thing about composition: It allows you to change capabilities of objects at runtime.
 
// the dog got wings

$dog->flyBehavior = new FlyBehavior();

echo "Dog: " . $dog->flyBehavior->fly(); // Dog: It flies !

Wrong Approach

The goal is to give to Bird (and other animals) the capability to fly. Wrong approach is to add a method in the superclass. This is bad when it isn't needed in every subclass.
 
abstract class Animal
{
    abstract function fly();
}

class Dog extends Animal
{
    // @Override
    public function fly() {
    }
}

class Bird extends Animal
{
    // @Override
    public function fly() {
        echo "Bird: I'm flying";
    }
}

$bird = new Bird();

$bird->fly(); // Bird: I'm flying
Why don't just add method fly() only in Bird class? Lots of duplicate code and we'll have many animals able to fly.
 
abstract class Animal {}

class Dog extends Animal {}

class Bird extends Animal
{
    public function fly() {
        echo "Bird: I'm flying";
    }
}

$bird = new Bird();

$bird->fly(); // Bird: I'm flying

Interface

An interface would also generate duplicate code. Also, a superclass change shouldn't break code in subclass and viceversa.
 
abstract class Animal {}

interface Fly
{
    public function fly();
}

class Dog extends Animal {}

class Bird extends Animal implements Fly
{
    // @Override
    public function fly() {
        echo "Bird: I'm flying";
    }
}

class Airplain extends Animal implements Fly
{
    // @Override
    public function fly() {
        echo "Airplain: I'm flying";
    }
}

$a = new Bird();
$a->fly(); // Bird: I'm flying

$b = new Airplain();
$b->fly(); // Airplain: I'm flying



  Last update: 236 days ago