Your code will break when, e.g. ducks quack with a different sounds. The boolean will only lead to other booleans into really hairy if-statements.
The strategy pattern is simple though. Take in this instance the quack method and place it into it's own class or interface. An interface in php would be a class that does not contain any implementation other than methods that are stubs (i.e. nothing happens when you call them).
class Quackable {
function quack() {}
}
That way you can create several quackable implementations:
class DuckQuack extends Quackable {
function quack() {
return "Quack!";
}
}
class SilentQuack extends Quackable {
function quack() {
return "";
// The decoy duck can't quack. It is silent.
}
}
And because we did it strategy pattern wise, we can add more types of "quackery":
class DoubleQuack extends Quackable {
function quack() {
return "Quackety-quack!"
}
}
The same can be applied to fly and swim methods for the Duck class. The way you implement a Duck class with a quackable would be like this (the quackable interface is supplied through the constructor, which is sort of how dependency injection works):
class Duck {
protected $quackable;
// The constructor
function __construct($quackable) {
$this->quackable = quackable;
}
function quack() {
echo $this->quackable->quack();
}
}
Implementing the mallard duck and decoy duck will be simple since you only need to supply what kind of quacks the duck should do:
class MallardDuck extends Duck {
function __construct() {
parent::__construct(new DuckQuack());
// we construct the mallard duck with a duck quack
}
}
class DecoyDuck extends Duck {
function __construct() {
parent::__construct(new SilentQuack());
// we construct the decoy duck with a silent quack
}
}
Using it all is simple:
$duck1 = new MallardDuck();
$duck2 = new DecoyDuck();
$duck1.quack(); // echoes out "Quack!"
$duck2.quack(); // echoes out "" (because decoy ducks don't quack)
I hope this all makes sense to you.
The decorator pattern is one that favours composition over inheritance [another OOP paradigm that is useful to learn about]
The main benefit of the decorator pattern - over subclassing is to allow more mix & match options. If you have, for instance, 10 different behaviours that a window can have, then this means - with subclassing - you need to create every different combination, which will also inevitably include a lot of code reuse.
However, what happens when you decide to add in a new behaviour?
With the decorator, you just add a new class which describes this behaviour, and that's it - the pattern allows you to effectively drop this in without any modification to the rest of the code.
With sub-classing, you've got a nightmare on your hands.
One question you asked was "how does subclassing change the parent class?" It's not that it changes the parent class; when it says an instance, it means any object you've 'instantiated' [if you're using Java or C#, for instance, by using the new
command]. What it's referring to is, when you add these changes to a class, you've got no choice for that change to be there, even if you don't actually need it.
Alternatively, you can put all his functionality into a single class with it turned on/off via flags... but this ends up with a single class that becomes larger and larger as your project grows.
It's not unusual to start your project this way, and refactor into a decorator pattern once you hit an effective critical mass.
An interesting point that should be made: you can add the same functionality multiple times; so you could, for instance, have a window with double, triple or whatever amount or borders as you require.
The major point of the pattern is to enable run-time changes: you may not know how you want the window to look until the program is running, and this allows you to easily modify it. Granted, this can be done via the subclassing, but not as nicely.
And finally, it allows for functionality to be added to classes that you may not be able to edit - for example in sealed/final classes, or ones provided from other APIs
Best Answer
I think the book “Head first design patterns” is correct.
As per Wikipedia, this pattern “allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class”. 'Extensions' are adding capability to an object statically and behaviors can be added by adding methods only, it may not need a new property (that is not a compulsory condition here). This stackoverflow question discussed similar stuff.
Delegation can be considered as a pattern and can be utilized to add a behaviors to an existing object as per decorator pattern. Have a look on following links: https://stackoverflow.com/questions/3929996/gof-explanation-of-the-decorator-pattern-is-confusing-or-just-plain-wrong and http://lgiordani.com/blog/2014/05/19/method-overriding-in-python/
Hope it will help. Thanks.