Когда нам нужен шаблон декоратора?

Когда необходимо использовать шаблон декоратора? Если возможно, приведите пример из реальной жизни, который хорошо подходит для этого шаблона.

31
задан james.garriss 15 January 2016 в 13:46
поделиться

8 ответов

Потоки в Java - подклассы InputStream и OutputStream являются прекрасными примерами шаблона декоратора.

В качестве примера, запись файла на диск:

File toWriteTo = new File("C:\\temp\\tempFile.txt");
OutputStream outputStream = new FileOutputStream(toWriteTo);    

outputStream.write("Sample text".getBytes());

Затем, если вам потребуются некоторые дополнительные функции, касающиеся записи на диск:

File toWriteTo = new File("C:\\temp\\tempFile.txt");
OutputStream outputStream = 
             new GZIPOutputStream(new FileOutputStream(toWriteTo));

outputStream.write("Sample text".getBytes());

Просто «сцепив» конструкторы, вы можете создать довольно мощные способы записи на диск . Прелесть этого способа в том, что позже вы можете добавить различные (в этом примере) реализации OutputStream . Кроме того, каждая реализация не знает, как работают другие - все они работают по одному и тому же контракту. Это также упрощает изолированное тестирование каждой реализации.


Существует множество «реальных» примеров того, как можно использовать шаблон декоратора. В голове несколько примеров:
  • Чтение и запись на диск (см. Выше)
  • Создание элементов пользовательского интерфейса, например добавление полос прокрутки в текстовые области и т. Д.

В шаблонах проектирования Head First Design Patterns есть еще несколько примеров из «реального мира». Кажется, что у O'Reilly есть их образец главы, которая находится на шаблоне декоратора, бесплатно; Google обнаружил эту ссылку: PDF

51
ответ дан 27 November 2019 в 21:35
поделиться

Взгляните на описание Фаулера; он дает конкретный пример, относящийся к книгам / видео и декоратору, "заимствованному", вы можете найти его здесь .

5
ответ дан 27 November 2019 в 21:35
поделиться

Два реальных примера:

Системы улучшения предметов в Diablo 2 и Final Fantasy 7. У оружия и доспехов есть гнезда или слоты. Во время игры игрок кладет в эти слоты улучшения (драгоценные камни, руны или материалы). Каждое улучшение имеет индивидуальный эффект (скажем, 8 очков огненного урона или 10% похищения маны). Итак, когда вы взмахиваете мечом, он наносит базовый урон плюс урон, добавляемый каждым улучшением, которое вы добавили. Это очень близко соответствует шаблону декоратора.

20
ответ дан 27 November 2019 в 21:35
поделиться

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

3
ответ дан 27 November 2019 в 21:35
поделиться

Из Gang of Four:

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

...

Декоратор соответствует интерфейсу компонента, который он декорирует, так что его присутствие прозрачно для клиентов компонента. Декоратор пересылает запросы компоненту и может выполнять дополнительные действия (например, рисовать границы) до или после пересылки. Прозрачность позволяет рекурсивно вложить декораторы, тем самым обеспечивая неограниченное количество дополнительных обязанностей.

8
ответ дан 27 November 2019 в 21:35
поделиться

Назначение шаблона Decorator:

Прикрепить дополнительные обязанности к объекту динамически. Декораторы предоставляют гибкую альтернативу созданию подклассов для расширения функциональности. [via В первую очередь: шаблоны проектирования ]

Самым интенсивным использованием шаблона декоратора являются графические интерфейсы пользователя и классы java.io. Существует бесплатная глава Head First: Design Patterns о шаблоне декоратора [link] , в которой приведены некоторые другие примеры:

Мы повторно рассмотрим типичное чрезмерное использование наследования, и вы узнаете, как украсьте свои классы во время выполнения, используя форма объектной композиции. Почему? Как только вы освоите технику украшения, вы сможете подарить ваши (или чужие) объекты новые обязанности без каких-либо изменения кода в базовом классы.

Вы также можете прочитать Шаблон декоратора на примере [PDF] , в котором шаблон декоратора используется в оценочном приложении.

3
ответ дан 27 November 2019 в 21:35
поделиться

Если вы знакомы с разработкой Swing на Java (наряду с другими инструментами графического интерфейса пользователя), вы увидите, что часто используется шаблон декоратора. У вас может быть конструктор, который принимает определенный компонент, а затем добавляет ему функциональность.

Вот хорошая статья, в которой в качестве примера используется Swing .

1
ответ дан 27 November 2019 в 21:35
поделиться

Вы просили пример реального мира, так вот: скачайте (или просмотрите) DonsProxy с github:

git://github.com/DonBranson/DonsProxy.git

DonsProxy в основном использует шаблон WireTap, чтобы позволить вам наблюдать или извлекать HTTP трафик, плюс он позволяет вам изменять поведение соединения для имитации неоптимальных соединений. Я использую паттерн Decorator для модификации каналов на основе опций пользователя. Опции командной строки или GUI (в зависимости от того, какой View они используют) позволяют вводить задержку и пропускную способность, среди прочего. Когда они вводят задержку, это добавляет LatencyDecorator к каналу; если они дросселируют пропускную способность, это добавляет ThrottleDecorator к каналу. Поскольку здесь используется паттерн декоратора, они могут смешивать и сочетать поведение по своему усмотрению.

2
ответ дан 27 November 2019 в 21:35
поделиться
Другие вопросы по тегам:

Похожие вопросы: