Разница между шаблоном декоратора и шаблоном делегирования
в чем разница между шаблоном декоратора и шаблоном делегирования (если есть) ? Я не хочу знать только о деталях реализации, но и о различиях в прецедентах и субъективной точке зрения, как их использовать.
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, который украшает репозиторий, и при чтении он выглядит в кэше, если его там нет, то он вызовет обычный метод репозитория, иначе он может просто вернуть кэшированную копию. Код не был изменен в классе репозитория, и пользователи этого класса ничего не знают о кэшировании.