Подтвердить что ты не робот

Рисунок декоратора по сравнению с дополнительным классом

Я могу решить проблему добавления функциональности, добавив подкласс, тогда почему я должен использовать шаблон декоратора, каково реальное преимущество шаблона декоратора?

4b9b3361

Ответ 1

из Рисунок декоратора в википедии

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

Весь шаблон декоратора - это динамическое добавление дополнительного поведения/функциональности, что, конечно, невозможно во время разработки.

из той же статьи:

Рисунок декоратора - это альтернатива подклассу. Подкласс добавляет поведение при компиляции времени, и изменение влияет на все экземпляры исходного класса; украшение может обеспечить новое поведение в время выполнения для отдельных объектов.

Ответ 2

Пример из GoF:

Предположим, что у вас есть класс TextView. Затем в каком-то месте вам нужен прокрученный текстовый вид, поэтому вы подклассифицируете TextView и создаете класс ScrolledTextView. А в другом месте вам нужна рамка вокруг текстового вида. Итак, вы снова подклассы и создаете BorderedTextView. Ну, теперь в каком-то месте вы хотите границу и прокрутите оба. Ни один из двух предыдущих подкласс не имеет обеих возможностей. Поэтому вам нужно создать третий. При создании ScrolledBorderedTextView вы фактически дублируете усилия. Этот класс вам не нужен, если у вас есть какой-либо способ создать возможности предыдущих двух. Ну, все может ухудшиться, и это может привести к ненужному взрыву класса.

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

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

Ответ 3

Книга шаблонов дизайна GoF определяет два основных преимущества использования Декораторов над подклассом:

  • Больше гибкости, чем статическая наследование. Образец декоратора обеспечивает более гибкий способ добавления ответственности перед объектами, чем может быть со статическим (кратным) наследование. С декораторами, обязанности могут быть добавлены и удалены во время выполнения прикрепляя и снимая их. В контраст, наследование требует создание нового класса для каждого дополнительная ответственность (например, BorderedScrollableTextView, BorderedTextView). Это приводит к росту для многих классов и увеличивает сложность системы. Более того, предоставление различного декоратора классы для конкретного компонента класс позволяет смешивать и сопоставлять обязанности.

    Декораторы также упрощают добавление собственность дважды. Например, для дайте TextView двойную границу, просто прикрепите два BorderDecorators. Наследование класса Border дважды в лучшем случае подвержен ошибкам.

  • Извлекает высокопрофессиональные классы в иерархии. Decorator предлагает платный подход к добавлению обязанности. Вместо того, чтобы пытаться для поддержки всех ожидаемых функций в сложном, настраиваемом классе, вы можете определить простой класс и добавьте функциональность постепенно Предметы декоратора. Функциональность может быть составлен из простых частей. Как результат, приложение не должно платить для функций, которые он не использует. Это также легко определить новые виды Декораторы, независимо от классы объектов, которые они расширяют, даже для непредвиденных расширений. простирающийся сложный класс стремится разоблачить детали, не связанные с обязанности, которые вы добавляете.

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

Если у вас есть TextWindow, к которому вы хотите добавить горизонтальную прокрутку, вертикальную прокрутку и границы независимо друг от друга и, при необходимости, с помощью подклассов, вам нужно будет определить подклассы для HorizontalScrollingTextWindow, VerticalScrollingTextWindow, HorizontalAndVerticalScrollingTextWindow, BorderedTextWindow, HorizontalScrollingBorderedTextWindow, VerticalScrollingBorderedTextWindow, HorizontalAndVerticaScrollingBorderedTextWindow и т.д., если вам нужен порядок прокрутки и границы.

С Decorators вам нужно всего лишь определить два декоратора прокрутки и один декоратор рамки.

Ответ 4

Подкласс может привести к проблемам с принципом замещения Лискова. Декоратор избегает этого.

Еще одно преимущество декоратора заключается в том, что вы пишете (вынуждены писать) на интерфейс. Это облегчает тестирование. Верно, что ваша иерархия объектов также может быть записана в интерфейс и, следовательно, имеет некоторые из тех же преимуществ, однако я могу протестировать отдельную реализацию класса декоратора изолированно. Я не могу сделать то же самое с подклассом, потому что всегда буду возвращать всю иерархию базовому классу. Я не могу проверить новый код в изоляции.

Используя узор декоратора и следуя принципу единой ответственности, я могу создать несколько декораторов и собрать их в любом случае. Я могу настроить это во время выполнения. В наследовании я либо должен создать каждую возможную ветвь (a- > b- > c, затем a- > c- > b, тем самым дублируя код и взрывая количество тестов), или я создаю 1 иерархию, а затем добавляю другую, когда это необходимо, но это запускает новый цикл тестирования/выпуска.

Вот почему вы хотели бы использовать шаблон декоратора вместо подкласса.

Ответ 5

Гибкость, причина ИМО.

Ответ 6

Вот различия, основанные на реальной реализации.

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

1) Sub-классификация в основном используется в случае расширения функциональности аналогичных  группа классов, которая хочет сохранить прежнюю функциональность, а также новую  в подклассах  и все экземпляры подклассов имеют одинаковую функциональность. Если мы  внести изменения в дочерние классы, а затем отразить все узлы  детских классов.  иерархическое отношение, аналогичная группа классов.

между родителями > ляющих > внуку.

Car- > Maruti 800- > Maruti 100 (будет иметь функцию Maruti 800, а также New)

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

Icircle cir = новый RedDecorator (новый круг()), украшающий круг красным цветом

Icircle cir = новый YellowDecorator (новый круг()), украшающий круг желтым цветом

Icircle cir = новый RedDecorator (новый YellowDecorator (новый круг())), украшающий

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

Таким образом, это уменьшает количество классов комбинации.

Вот полезная ссылка для рисунка декоратора

https://www.tutorialspoint.com/design_pattern/decorator_pattern.htm