书上说:
装饰器模式可用于扩展(装饰)某个对象的功能
我有一只兔子动物。例如,我希望我的兔子有爬行动物的皮肤。只想用爬行动物的皮肤装饰一只普通的兔子。
我有代码。首先,我有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 */
}
我为我的兔子创建课程:
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;
}
}
到目前为止一切正常。然后我创建扩展的抽象AnimalDecorator
类Animal
:
abstract class AnimalDecorator extends Animal {
protected $animal;
public function __construct(Animal $animal) {
$this->animal = $animal;
}
}
问题来了。注意AnimalDecorator
也从类中获取所有抽象方法Animal
(在这个例子中只有两个,但实际上可以有更多)。
然后我创建ReptileSkinDecorator
扩展的具体类AnimalDecorator
。它还具有相同的两个抽象方法Animal
:
class ReptileSkinDecorator extends AnimalDecorator {
public function getSkinColor() {
$skin = $this->animal->getSkinType();
$skin = "reptile";
return $skin;
}
}
最后我想用爬行动物的皮肤装饰我的兔子:
$reptileSkinRabbit = ReptileSkinDecorator(new Rabbit());
但我不能这样做,因为我在ReptileSkinDecorator
课堂上有两个抽象方法。他们是:
abstract public function setSleep($hours);
abstract public function setEat($food);
所以,我不仅要重新装饰皮肤,还必须重新装饰setSleep()
和setEat();
方法。但我不需要。
在所有书籍示例中,类中始终只有一个抽象方法Animal
。当然它会起作用。但是在这里我只是做了一个非常简单的现实生活示例并尝试使用装饰器模式,如果不在类中实现这些抽象方法,它就无法工作ReptileSkinDecorator
。
这意味着如果我想使用我的示例,我必须创建一个全新的兔子并为其实现自己的方法setSleep()
和setEat()
方法。好吧,就这样吧。但是后来这个全新的兔子有Rabbit
我传递给的 commont 实例ReptileSkinDecorator
:
$reptileSkinRabbit = ReptileSkinDecorator(new Rabbit());
我有一个普通的兔子实例,它在 reptileSkinRabbit 实例中有自己的方法,而它又具有自己的 reptileSkinRabbit 方法。我有兔子在兔子。但我想我不必有这种可能。
我不正确地理解 Decarator 模式。在我对这种模式的理解中,请您指出我的示例中的任何错误。
谢谢你。