What is there so useful in the Decorator Pattern? My example doesn't work
Posted
by
Green
on Stack Overflow
See other posts from Stack Overflow
or by Green
Published on 2012-06-02T16:04:19Z
Indexed on
2012/06/02
16:41 UTC
Read the original article
Hit count: 284
The book says:
The decorator pattern can be used to extend (decorate) the functionality of a certain object
I have a rabbit animal. And I want my rabbit to have, for example, reptile skin. Just want to decorate a common rabbit with reptile skin.
I have the code. First I have abstract class Animal
with everythig that is common to any animal:
abstract class Animal {
abstract public function setSleep($hours);
abstract public function setEat($food);
abstract public function getSkinType();
/* and more methods which for sure will be implemented in any concrete animal */
}
I create class for my rabbit:
class Rabbit extends Animal {
private $rest;
private $stomach;
private $skinType = "hair";
public function setSleep($hours) {
$this->rest = $hours;
}
public function setFood($food) {
$this->stomach = $food;
}
public function getSkinType() {
return $this->$skinType;
}
}
Up to now everything is OK. Then I create abstract AnimalDecorator
class which extends Animal
:
abstract class AnimalDecorator extends Animal {
protected $animal;
public function __construct(Animal $animal) {
$this->animal = $animal;
}
}
And here the problem comes. Pay attention that AnimalDecorator
also gets all the abstract methods from the Animal
class (in this example just two but in real can have many more).
Then I create concrete ReptileSkinDecorator
class which extends AnimalDecorator
. It also has those the same two abstract methods from Animal
:
class ReptileSkinDecorator extends AnimalDecorator {
public function getSkinColor() {
$skin = $this->animal->getSkinType();
$skin = "reptile";
return $skin;
}
}
And finaly I want to decorate my rabbit with reptile skin:
$reptileSkinRabbit = ReptileSkinDecorator(new Rabbit());
But I can't do this because I have two abstract methods in ReptileSkinDecorator
class. They are:
abstract public function setSleep($hours);
abstract public function setEat($food);
So, instead of just re-decorating only skin I also have to re-decorate setSleep()
and setEat();
methods. But I don't need to.
In all the book examples there is always ONLY ONE abstract method in Animal
class. And of course it works then. But here I just made very simple real life example and tried to use the Decorator pattern and it doesn't work without implementing those abstract methods in ReptileSkinDecorator
class.
It means that if I want to use my example I have to create a brand new rabbit and implement for it its own setSleep()
and setEat()
methods. OK, let it be. But then this brand new rabbit has the instance of commont Rabbit
I passed to ReptileSkinDecorator
:
$reptileSkinRabbit = ReptileSkinDecorator(new Rabbit());
I have one common rabbit instance with its own methods in the reptileSkinRabbit instance which in its turn has its own reptileSkinRabbit methods. I have rabbit in rabbit. But I think I don't have to have such possibility.
I don't understand the Decarator pattern right way. Kindly ask you to point on any mistakes in my example, in my understanding of this pattern.
Thank you.
© Stack Overflow or respective owner