Когда необходимо использовать шаблон декоратора? Если возможно, дайте мне пример реального мира, который хорошо подходит для шаблона.
Когда нам нужен узор декоратора?
Ответ 1
Потоки в 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
позже. Кроме того, каждая реализация не знает, как работают другие - все они работают только с одним и тем же контрактом. Это также делает тестирование каждой реализации очень простым в изоляции.
Существует множество примеров "реального мира", в которых можно использовать шаблон декоратора. В верхней части головы несколько примеров:
- Чтение и запись на диск (выше)
- Построение элементов пользовательского интерфейса, таких как добавление полос прокрутки в текстовые области и т.д.
В главах First Design Patterns есть еще несколько примеров "реального мира". Кажется, что O'Reilly имеет свой образец главы, который находится на Decorator Pattern, бесплатно; Google обнаружил эту ссылку: PDF
Ответ 2
Два реальных примера:
Системы обновления предметов в Diablo 2 и Final Fantasy 7. Оружие и доспехи имеют гнезда или слоты. Во время игры игрок помещает в эти слоты апгрейды (драгоценные камни, руны или материю). Каждое обновление имеет индивидуальный эффект (скажем, 8 очков урона от огня или 10% маны пиявки). Поэтому, когда вы качаете свой меч, он наносит базовый урон плюс урон, добавленный каждым обновленным обновлением. Это очень близко соответствует рисунку декоратора.
Ответ 3
От группы четырех:
Инструмент графического пользовательского интерфейса, например, должен позволить вам добавлять такие свойства, как границы или поведения, такие как прокрутка к любому компоненту пользовательского интерфейса.
...
Декоратор соответствует интерфейсу компонента, который он украшает, чтобы его присутствие было прозрачным для клиентских компонентов. Декоратор отправляет запросы компоненту и может выполнять дополнительные действия (например, рисование границы) до или после пересылки. Прозрачность позволяет регенерировать декореры, тем самым позволяя неограниченное количество добавленных обязанностей.
Ответ 4
Посмотрите на описание Фаулера; он дает конкретный пример, относящийся к книгам/видео и декоратору "заемный", вы можете найти его здесь.
Ответ 5
Цель шаблона Decorator заключается в следующем:
Прилагайте дополнительные обязанности к объекту динамически. Декораторы обеспечивают гибкую альтернативу подклассу для расширения функциональности. [через Head First: шаблоны проектирования]
Самым интенсивным использованием декоратора является графический интерфейс и классы java.io. Существует бесплатная глава главы First: Design Patterns о шаблоне декоратора [link], которые содержат некоторые другие примеры:
Хорошо пересмотреть типичное чрезмерное использование наследования, и вы узнаете, как украсить свои классы во время работы, используя форма композиции объекта. Зачем? Как только вы узнаете украшение, вы сможете дать ваш (или кто-то elses) объект новый ответственности без каких-либо изменения кода в классы.
Вы также можете прочитать шаблон декоратора по примеру [PDF], в котором шаблон декоратора используется в оценочном приложении.
Ответ 6
Один из самых крутых - и наиболее буквальных - использования, которые я видел, - это реализовать отмену способности, назад в плохие старые дни одноуровневой отмены. Для векторной программы рисования с несколькими выбранными объектами разных цветов: выполните команду, чтобы изменить все их цвета. И сделать его недействительным. Это было сделано путем применения Decorator, который был вызван в потоке getColor(), так что, когда они были нарисованы, они были нарисованы в новом цвете; по существу, собственные методы getColor() были отменены. Таким образом, они появились в новом цвете. Отменить было так же просто, как удалить Decorator из всех объектов; совершение действия было вопросом применения цвета от Декоратора к объектам, а затем его удаления. Гораздо проще, чем хранить таблицу, в которой были окрашены объекты и какими были их оригинальные цвета.
Ответ 7
Вы просили привести пример из реальной жизни, так что вот вам: скачать (или просмотреть) DonsProxy с github:
мерзавец://github.com/DonBranson/DonsProxy.git
DonsProxy в основном использует шаблон WireTap, чтобы позволить вам наблюдать или извлекать HTTP-трафик, плюс он позволяет вам изменять поведение соединения для имитации неоптимальных соединений. Я использую шаблон Decorator для изменения каналов в зависимости от пользовательских настроек. Параметры командной строки или графического интерфейса (в зависимости от того, какое представление они используют), среди прочего, позволяют вводить задержку и пропускную способность. Когда они вводят задержку, это добавляет LatencyDecorator к каналу; если они ограничивают полосу пропускания, это добавляет ThrottleDecorator к каналу. Поскольку при этом используется шаблон декоратора, они могут смешивать и сопоставлять поведение со своим сердцем.
Ответ 8
Если вы знакомы с разработкой Swing на Java (наряду с другими инструментами GUI), вы увидите, что шаблон декоратора используется много. У вас может быть конструктор, который принимает определенный компонент, а затем добавляет ему функциональность.
Вот хорошая статья, в которой используется Swing в качестве примера.
Ответ 9
Когда необходимо использовать шаблон декоратора?
Используйте Decorator_pattern, если
- Обязанности и поведение объекта должны динамически добавляться/удаляться
- Конкретные реализации должны быть отделены от обязанностей и поведения Подкласс
- слишком дорогостоящий, чтобы динамически добавлять/удалять обязанности.
Если возможно, дайте мне пример реального мира, который хорошо подходит для шаблона.
Я придумал свой собственный вендинг-автомат.
Описание проблемы: Вычислите цену напитка (чай или кофе), добавив один или несколько ароматов, таких как сахар, лимон и т.д.
Пример кода и пояснения доступны @