Я думаю, вы неправильно поняли Декоратор. Вы думаете о простом случае расширения конкретного класса дополнительными функциями. В этом случае, да, в большинстве языков OO производный класс может просто позволить своему суперклассу обрабатывать любые нереализованные методы.
class Base {
function foo() {
return "foo";
}
function bar() {
return "bar";
}
}
// Not what we think of as a Decorator,
// really just a subclass.
class Decorator extends Base {
// foo() inherits behavior from parent Base class
function bar() {
return parent::bar() . "!"; // add something
}
}
Класс Decorator не расширяет базовый класс своего "украшенного" класса. Это другой тип, в котором есть объект-член оформленного класса. Таким образом, он должен реализовывать тот же интерфейс, если только вызывать соответствующий метод декорированного объекта.
class Decorator { // extends nothing
protected $base;
function __construct(Base $base) {
$this->base = $base;
}
function foo() {
return $base->foo();
}
function bar() {
return $base->foo() . "!"; // add something
}
}
Возможно, стоит определить интерфейс (если ваш язык поддерживает такие вещи) как для украшенного класса, так и для класса Decorator. Таким образом, вы можете проверить во время компиляции, что Decorator реализует тот же интерфейс.
interface IBase {
function foo();
function bar();
}
class Base implements IBase {
. . .
}
class Decorator implements IBase {
. . .
}
Re: @Yossi Dahan's comment: Я вижу неоднозначность в статье в Википедии, но если вы внимательно прочитаете, она говорит, что декорируемый компонент - это поле в объекте декоратора, и что этот компонент передается в качестве аргумента конструктору декоратора. Это отличается от наследования.
Хотя в статье в Википедии говорится, что декоратор наследуется от компонента, вы должны думать об этом как о реализации интерфейса, как я показал в примере с PHP выше. Декоратор все еще должен прокси для объекта компонента, чего не было бы, если бы он унаследовал. Это позволяет декоратору декорировать объект любого класса, который реализует этот интерфейс.
Вот некоторые отрывки из «Шаблонов проектирования: элементы многократно используемого объектно-ориентированного программного обеспечения» Гаммы, Хелма, Джонсона и Влиссида:
декоратор
Намерение
Прикрепить дополнительные обязанности к объекту
динамически. Декораторы обеспечивают
гибкая альтернатива подклассам
для расширения функциональности.
Мотивация
...
Декоратор соответствует интерфейсу
компонент, который он украшает так, чтобы его
присутствие прозрачно для
клиенты компонента.
Участники
- декоратор
поддерживает ссылку на объект Component и определяет интерфейс
соответствует интерфейсу компонента.