Основное преимущество, которое вы получаете с помощью шаблона Decorator, заключается в том, что для клиентского кода он прозрачен. Они не должны знать о декораторе, они могут рассматривать его как обычную старую конкретную реализацию базового интерфейса:
ThingDoer thingDoer = new ThingDoerDecorator(new AwesomeThingDoer());
ThingDoer otherThingDoer = new AwesomeThingDoer();
thingDoer.doThing();
otherThingDoer.doThing();
Это возможно только потому, что декоратор реализует тот же интерфейс, что вещь это декорирование. Если он не реализует этот интерфейс, вы теряете большую часть мощности этого шаблона.
Однако иногда имеет смысл иметь базовый декоратор, реализующий.
abstract class BaseThingDoerDecorator implements ThingDoer {
private ThingDoer thingDoer;
protected BaseDecorator(ThingDoer thingDoer) {
this.thingDoer = thingDoer;
}
@Override
public void doThing() {
thingDoer.doThing();
}
}
Теперь становится практичным, чтобы сделать такие вещи, как это:
ThingDoer thingDoer = new BaseThingDoerDecorator(new AwesomeThingDoer()) {
@Override
public void doThing() {
System.out.println("This is an anonymous decorator");
super.doThing();
}
};
Или, может быть, вы хотите, чтобы все ваши декораторы быть защищены от исключений в базовом компоненте:
abstract class BaseThingDoerDecorator implements ThingDoer {
// Same as above...
// ...
@Override
public void doThing() {
try {
thingDoer.doThing();
} catch (Exception e) {
log(e);
}
}
}
Какие программирования О каком языке речь? –
Это должно быть применимо к любому языку, который поддерживает наследование или интерфейсы. Почему вы спрашиваете? – neverendingqs
@neverendingqs нет интерфейса декоратора, есть дополнительный _abstract_ decorator. – qujck