Когда нам нужен шаблон декоратора? - PullRequest
31 голосов
/ 13 августа 2010

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

Ответы [ 9 ]

51 голосов
/ 13 августа 2010

Streams в 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 содержит еще несколько примеров из "реального мира".Похоже, что у О'Рейли есть образец главы, которая посвящена Декоратору, бесплатно;Google обнаружил эту ссылку: PDF

20 голосов
/ 13 августа 2010

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

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

8 голосов
/ 13 августа 2010

Из Gang of Four:

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

...

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

5 голосов
/ 13 августа 2010

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

3 голосов
/ 13 августа 2010

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

3 голосов
/ 13 августа 2010

Целью шаблона Decorator является:

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

Наиболее интенсивное использование шаблона декоратора - это GUI и классы java.io.Существует бесплатная глава Head First: Шаблоны проектирования о шаблоне декоратора [ссылка] , в которых приведены некоторые другие примеры:

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

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

2 голосов
/ 13 августа 2010

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

мерзавец: //github.com/DonBranson/DonsProxy.git

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

1 голос
/ 13 августа 2010

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

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

0 голосов
/ 13 августа 2016

Когда необходимо использовать шаблон декоратора?

Использовать Decorator_pattern , если

  1. Обязанности и поведение объекта должны динамически добавляться / удаляться
  2. Конкретные реализации должны быть отделены от обязанностей и поведения
  3. создание подклассов слишком дорого для динамического добавления / удаления обязанностей

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

Я придумала свой собственный декоратор торгового автомата.

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

Пример кода и пояснения доступны @

Когда использовать шаблон декоратора?

...