Разница между композитным рисунком и рисунком декоратора? - PullRequest
46 голосов
/ 10 февраля 2010

В чем разница между составным рисунком и рисунком декоратора?

Ответы [ 7 ]

41 голосов
/ 10 февраля 2010

Они обычно идут рука об руку. При этом использование составного шаблона часто приводит также к использованию шаблона декоратора.

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

http://en.wikipedia.org/wiki/Composite_pattern

Шаблон декоратора позволяет объекту полностью содержать другой объект, так что использование декоратора выглядит идентично содержащемуся объекту. Это позволяет декоратору изменять поведение и / или содержимое того, что он инкапсулирует, без изменения внешнего вида объекта. Например, вы можете использовать декоратор для добавления выходных данных журнала об использовании содержащегося элемента без изменения поведения содержащегося элемента.

http://en.wikipedia.org/wiki/Decorator_pattern

40 голосов
/ 05 января 2012

Структура составного шаблона и декоратора выглядят одинаково, но имеют разные намерения.

Composite дает унифицированный интерфейс к листу и композиту.

Декоратор Декоратор дает дополнительные возможности для листьев, давая при этом унифицированный интерфейс.


Примеры * * 1016 Составной шаблон : классические папки и файлы Windows. Папки Windows являются композитными. файлы листья. Двойной щелчок по любому из них открывает файл / папку - двойной щелчок по унифицированному интерфейсу. Шаблон декоратора : Буферизованные io - java.io.FileWriter и java.io.BufferedWriter оба расширяются java.io.Writer. java.io.BufferedWriter является составным, а FileWriter является листом. BufferedWriter добавляет дополнительную ответственность (или функцию) буферизации к FileWriter. write() - это унифицированный интерфейс, а буферизация - дополнительная функция.

18 голосов
/ 29 января 2013

Декоратор можно рассматривать как вырожденный композит с одним компонентом. Однако декоратор добавляет дополнительные обязанности - он не предназначен для агрегирования объектов.

Это то, что сказано в «Конструктивных элементах многоразового объектно-ориентированного программного обеспечения» группой из четырех человек.

5 голосов
/ 10 февраля 2010

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

Декораторы позволяют вам прозрачно добавлять функциональность, обычно единственную, в класс без клиентов, для которых экземпляры класса должны знать, что там находится декоратор - например, декоратор login_required для представления в Django Вызывает исключение, если пользователь не вошел в систему, но в противном случае представление ведет себя так, как без декоратора.

В обоих случаях у вас есть один объект, встроенный в другой, но то, что вы пытаетесь достичь, возможно, отличается.

3 голосов
/ 10 декабря 2015

Различия в структуре

Вот диаграммы классов из книги GoF, воспроизведенные с использованием PlantUML.

GoF Decorator class diagram

GoF Composite class diagram

Различия в намерениях

Цель Decorator состоит в том, чтобы украсить один компонент (диаграмма UML действительно должна показывать кратность единицы для декорированного компонента), тогда как цель Composite состоит в группировании компонентов в целом в Composite (опять же, UML должен показывать Composite, содержащий один или несколько Components).

Декоратор имеет целью добавить поведение (улучшить поведение метода Operation()) через ConcreteDecorators, тогда как Composite стремится собирать Компоненты.

1 голос
/ 31 августа 2016

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

Это возможно благодаря композиции: Decorator содержит Component и одновременно реализует интерфейс Component.

Шаблон Composite описывает, что группа объектов должна обрабатываться так же, как отдельный экземпляр объекта. Назначение составной части состоит в том, чтобы «объединить» объекты в древовидные структуры для представления иерархий части-целого.

Реализация составного шаблона позволяет клиентам одинаково обрабатывать отдельные объекты и композиции.

Даже если структура кажется одинаковой, намерение и варианты использования различны.

Варианты использования для Декоратор pattern:

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

Ключ Различия между этими двумя шаблонами:

  1. Декоратор позволяет добавлять обязанности к объектам без создания подклассов. Композит фокусируется не на украшении, а на представлении
  2. Декоратор добавляет / снимает дополнительные обязанности - не предназначен для агрегирования объектов.

Полезные посты в SE для лучшего понимания:

Шаблон декоратора для ввода / вывода

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

0 голосов
/ 27 января 2018

Композитный:

  • Является ли древовидная структура с использованием рекурсии.
  • Leaf и Composite имеют одинаковый интерфейс
  • Единство между объектами

декоратор:

  • Содержит другую сущность.
  • Добавление новых функций в составной объект без его изменения.
...