Шаблон дизайна декоратора: почему вызывать функции в цепочке, а не в цикле?

В шаблоне проектирования декоратора мы оборачиваем объекты одинакового типа друг в друга, а затем в цепочке вызываем одну и ту же функцию из них. Это позволяет добавить функциональность. Теперь почему бы нам не сделать то же самое не в цепи, а в цикле. Я имею в виду, что мы можем хранить все объекты в векторе (map?), И если вызывается функция, мы можем делегировать этот вызов каждому элементу вектора. Купив это, мы получим даже такое преимущество, как если бы я хотел получить доступ (чтобы получить состояние) к конкретному декоратору, я мог получить к нему прямой доступ и не добавлять общедоступную функцию к интерфейсу, так что все декораторы должны переопределять, но в большинстве им эта функция ничего не должна делать. Например, в классическом примере с окна и полосы прокрутки если я не хочу знать, заблокирована ли горизонтальная полоса прокрутки, мне нужно добавить функцию isHor horizontalScrollBarLocked в WindowDecorator, что не имеет смысла для вертикальной полосы прокрутки и многих других декораторов тоже.

РЕДАКТИРОВАТЬ (добавив код, чтобы прояснить, что я говорю):

// the Window interface class
public interface Window {
public void draw(); // draws the Window
public String getDescription(); // returns a description of the Window
}

// extension of a simple Window without any scrollbars
class SimpleWindow implements Window {
public void draw() {
// draw window
}

public String getDescription() {
return "simple window";
}
}

// abstract decorator class - note that it implements Window
abstract class WindowDecorator implements Window {
protected Window decoratedWindow; // the Window being decorated

public WindowDecorator (Window decoratedWindow) {
this.decoratedWindow = decoratedWindow;
}
public void draw() {
decoratedWindow.draw(); //delegation
}
public String getDescription() {
return decoratedWindow.getDescription(); //delegation
}
}// the first concrete decorator which adds vertical scrollbar functionality
class VerticalScrollBarDecorator extends WindowDecorator {
public VerticalScrollBarDecorator (Window decoratedWindow) {
super(decoratedWindow);
}

@Override
public void draw() {
super.draw();
drawVerticalScrollBar();
}

private void drawVerticalScrollBar() {
// draw the vertical scrollbar
}

@Override
public String getDescription() {
return super.getDescription() + ", including vertical scrollbars";
}
}// the second concrete decorator which adds horizontal scrollbar functionality
class HorizontalScrollBarDecorator extends WindowDecorator {
public HorizontalScrollBarDecorator (Window decoratedWindow) {
super(decoratedWindow);
}

@Override
public void draw() {
super.draw();
drawHorizontalScrollBar();
}

private void drawHorizontalScrollBar() {
// draw the horizontal scrollbar
}

@Override
public String getDescription() {
return super.getDescription() + ", including horizontal scrollbars";
}
}

public class DecoratedWindowTest {
public static void main(String[] args) {
// create a decorated Window with horizontal and vertical scrollbars
Window decoratedWindow = new HorizontalScrollBarDecorator (
new VerticalScrollBarDecorator (new SimpleWindow()));

// print the Window's description
System.out.println(decoratedWindow.getDescription());
}
}

Теперь я хочу знать, заблокирована ли горизонтальная полоса прокрутки для decoratedWindow, Что я должен делать? Мне нужно добавить isHorizontalScrollBarLocked общественная функция в Window и переопределить его в HorizontalScrollBarDecorator и во всех других классах, которые реализуют WindowVerticalScrollBarDecorator WindowDecorator) право?

С другой стороны, я мог бы создать фасад, который будет представлять мое окно. В этом фасаде у меня будет список Window объекты и эти объекты будут SimpleWindow, VerticalScrollBarDecorator, HorizontalScrollBarDecoratorи т. д. И если пользователь будет вызывать функцию draw фасада, я в петле все обзвоню draw функции Windowв списке. В противном случае, если пользователь позвонит isHorizontalScrollBarLocked только на HorizontalScrollBarDecorator объект.

-1

Решение

Предлагаемое вами изменение шаблона декоратора не будет в силе. Фасад, который вы хотите реализовать, на самом деле не «украшает», так сказать, какую-либо функциональность. Позволь мне объяснить…

Рассмотрим сценарий, в котором вы хотите использовать BufferedWriter записать байты в выходной поток. BufferedWriterОтветственность заключается в том, чтобы дождаться накопления достаточного количества байтов, прежде чем он выполнит свою дорогостоящую операцию — запись ввода-вывода. Это decorates нормальный поток, объединяющий несколько операций записи в пакеты.

Если бы у вас был фасад, делегаты которого звонили по всей цепочке декораторов, какой смысл использовать BufferedWriter ? Фасад не знает, в каком состоянии находится BufferedWriter находится в, так что он не может принять вызов о том, чтобы выполнить цепочку полностью вниз.

2

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector