PHP5. Композиция на примере паттерна Стратегия

Один из принципов проектирования гласит - отдавайте предпочтение композиции перед наследованием. Для примера механизма композиции рассмотрим такой паттерн проектирования как Стратегия (определяет семейство алгоритмов, инкапсулирует каждый из них и обеспечивает их взаимозаменяемость. Он позволяет модифицировать алгоритмы независимо от их использования на стороне клиента). Для этого рассмотрим класс Duck, на основе которого попытаемся реализовать данный паттерн:

    abstract class Duck {
       
        protected $flyBehavior;
        protected $quackBehavior;
       
        public function __construct() {}
       
        public abstract function display();
       
        public function setFlyBehavior(FlyBehavior $fb) {
            $this->flyBehavior = $fb;
        }
       
        public function setQuackBehavior(QuackBehavior $qb) {
            $this->quackBehavior = $qb;
        }
       
        public function performFly() {
            $this->flyBehavior->fly();
        }
       
        public function performQuack() {
            $this->quackBehavior->quack();
        }
       
        public function swim() {
            echo "All ducks float, even decoys!";
            echo "<br/>";
        }
       
    }
   
    class MallardDuck extends Duck {
   
        public function __construct() {
            $this->flyBehavior = new FlyWithWings();
            $this->quackBehavior = new Quack();
        }
       
        public function display() {
            echo "I`m a real Mallard duck";
            echo "<br/>";
        }
   
    }
   
    interface FlyBehavior {
        public function fly();
    }
   
    class FlyWithWings implements FlyBehavior {
        public function fly() {
            echo "I`m flying";
            echo "<br/>";
        }
    }
   
    class FlyNoWay implements FlyBehavior {
        public function fly() {
            echo "I can`t fly";
            echo "<br/>";
        }
    }
   
    interface QuackBehavior {
        public function quack();
    }
   
    class Quack implements QuackBehavior {
        public function __construct() {}
        public function quack() {
            echo "Quack";
            echo "<br/>";
        }
    }
   
    class MuteQuack implements QuackBehavior {
        public function __construct() {}
        public function quack() {
            echo "<< Silence >>";
            echo "<br/>";
        }
    }
   
    class Squeak implements QuackBehavior {
        public function __construct() {}
        public function quack() {
            echo "Squeak";
            echo "<br/>";
        }
    }
   
    class ModelDuck extends Duck {
   
        public function __construct() {
            $this->flyBehavior = new FlyNoWay();
            $this->quackBehavior = new Quack();
        }
   
        public function display() {
            echo "I`m a model duck";
            echo "<br/>";
        }
   
    }
   
    class FlyRocketPowered implements FlyBehavior {
   
        public function fly() {
            echo "I`m flying with a rocket";
            echo "<br/>";
        }
   
    }

    $mallard = new MallardDuck();
    $mallard->performQuack();                            // Quack
    $mallard->performFly();                                // I`m flying
   
    $model = new ModelDuck();
    $model->performFly();                                // I can`t fly
    $model->setFlyBehavior(new FlyRocketPowered());
    $model->performFly();                                // I`m flying with a rocket


Более общее представление можно получить по следующему рисунку (обратите внимание на композитные связи)