прошу прощения за Ctrl + Enter :)
необходимо создать интерфейс:
interface IDecorable {
/**
* @return IDecorable
*/
removeDecorator(IDecorable $decorator);
}
декорируемый обьект должен реализовать интерфейс с помощью заглушки:
//....
/**
* @return IDecorable
*/
removeDecorator(IDecorable $decorator) {
return $this;
}
//...
а все декораторы могут наследоваться от абстрактного декоратора в котором будет вот такая реализация данного интерфейса:
//....
/**
* @var IDecorator
*/
private $decorableObject;
/**
* @return IDecorable
*/
removeDecorator(IDecorable $decorator) {
if($decorator == $this) {
return $this->decorableObject;
}
$decorable = $this->decorableObject->removeDecorator($decorator);
if($decorable != $this->decoratedObject) {
$this->decoratedObject = $decorable;
}
return $this;
}
//...
Таким образом обьекты смогут использоваться следующим образом:
$decorated = $decorated->removeDecorator($decorated);
Такой код может удалить самый верхний декоратор обьекта или вернет сам обьект если у него нет декораторов.
Для удаления произвольного декоратора из цепочки нужно передать в качестве параметра этот декоратор или декоратор с аналогичными свойствами:
$decorated = $decorated->removeDecorator($someOtherDecorator);