Разница между шаблоном декоратора и шаблоном делегирования

в чем разница между шаблоном декоратора и шаблоном делегирования (если есть) ? Я не хочу знать только о деталях реализации, но и о различиях в прецедентах и субъективной точке зрения, как их использовать.

EDIT: можете ли вы указать исходный код (в проекте ОС), где эти шаблоны (особенно Делегирование, потому что украшение используется в классах JAVA IO) используются. Я ищу реальное использование не только пример муляж. Может быть, эти узоры одинаковы, отличается только название. Не стесняйтесь писать это мнение.

2 ответов


декоратор использует делегирование, но очень определенным образом.

делегирование (или композиция) - это не столько шаблон, сколько общий способ построения сложного поведения путем координации использования нескольких других объектов. Он часто используется в наборе или статическим способом. Под "set или static" я подразумеваю что-то вроде этого:

class Delegator {
  private final ClassA a = new ClassA();
  private final ClassB b = new ClassB();

  public void doWork() {
     a.setup();
     final ResFromA resa = a.getRes();
     b.setup();
     b.consume(resa);
  }

}

обратите внимание, что Делегатор не имеет общего типа или интерфейса с ClassA или ClassB и знает точный тип обоих a и b.

декоратор динамический способ использования делегирования для добавления поведения в логическую сущность во время выполнения. В Decorator все сущности имеют общий интерфейс и используют делегирование для объединения своей работы.

public interface Item {
  public void drawAt(final int x, final int y);
}

public class CircleAround implements Item {
  private final Item wrapped;
  private final int radius;

  public CircleAround(public final Item wrapped, public final int radius) {
    this.wrapped = wrapped;
    this.radius = radius;
  }

  public void drawAt(final int x, final int y) {
    // First handle whatever we are wrapping
    wrapped.drawAt(x,y);
    // Then add our circle
    Graphics.drawCircle(x, y, radius);
  }

}

обратите внимание, что в отличие от первого примера CircleAround не знает точный тип элемента, который он обертывает, и разделяет с ним общий интерфейс.


Я думаю, что "шаблон делегирования" провалит лакмусовую бумажку того, что является или не является шаблоном довольно ясно. Например, люди все еще говорят: "Я знаю заводскую модель" все время. Нет шаблона "Фабрика". Это идиома (ср. Advanced C++ by James Coplien). Эта страница тоже довольно слабая; я не рассматриваю простое делегирование как инверсию ответственности.

декоратор используется, когда код должен быть дополнен. Декоратор сам обтекает decoratee и по-прежнему называет свои методы, он просто делает вещи до или после. Это одна из причин, почему люди часто говорят о декораторе, когда возникают аспекты: это шаблон, который опирается на посредничество, а не сотрудничество с его когортой. (Именно поэтому во многих случаях, например, когда у вас нет источника, вы должны использовать декоратора.)

декоратор работает лучше всего, когда вы хотите взять что-то, что работает, и сделать что-то еще, но не изменить интерфейс совсем. Представьте, что у вас есть класс репозитория, который выдает интерфейс, в котором есть методы CRUD. Теперь вы хотите добавить кэширование. Вы можете сделать CachedRepository, который украшает репозиторий, и при чтении он выглядит в кэше, если его там нет, то он вызовет обычный метод репозитория, иначе он может просто вернуть кэшированную копию. Код не был изменен в классе репозитория, и пользователи этого класса ничего не знают о кэшировании.