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

Основные темы, рассматриваемые на уроке:
00:36 1 Метафора
11:47 2 Структура паттерна на языке UML
13:30 3 Структура паттерна на языке C#
15:08 4 Детальное рассмотрения паттерна (с использованием метафоры)
18:15 5 Участники и мотивация
19:13 6 Применимость и результаты
20:11 7 Назначение паттерна
22:42 8 Предостережения
25:16 9 Использование паттерна

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

Для просмотра полной версии видеокурса и получения доступа к дополнительным учебным материалам Вам необходимо оформить подписку
Оформить подписку

Паттерн Decorator

Название

Декоратор

Также известен как

Wrapper (Обертка)

Классификация

По цели: структурный

По применимости: к объектам

Частота использования

Средняя               -   1 2 3 4 5

Назначение

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

Введение

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

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

Для того чтобы летчик истребитель мог выполнять боевое задание – охранять воздушные границы государства, самого летчика недостаточно. Потребуются следующие компоненты: специальный (высотно-компенсирующий) костюм и самолет СУ-47. Для организации полета потребуется летчика поместить в костюм, а костюм поместить в самолет. Обратите внимание, летчик не касается своим телом кресла самолета, так же, все взаимодействие с самолетом происходит через костюм. Получается некая цепочка связанных объектов: самолеткостюмлетчик. Почему именно такая последовательность? Потому что для вражеского пилота, целью в бою будет именно самолет Су-47, а не летчик, который управляет самолетом. Поэтому, если представить такую ситуацию объектно-ориентировано, то получается, что объект-самолет ссылается на объект-костюм, а объект-костюм ссылается на объекта-летчика (по-другому можно сказать, летчик декорирован костюмом, а костюм декорирован самолетом). Если представить наоборот (летчиккостюм - самолет), то получится, что движущая сила летчика тащит за собой костюм, а костюм тащит за собой самолет, что может показаться вздорным.

Структура паттерна на языке UML

См. пример к главе: \009_Decorator\001_Decorator

Структура паттерна на языке C#

См. пример к главе: \009_Decorator\001_Decorator

Участники

  • Component - Компонент:

Предоставляет интерфейс для объектов, которые могут быть декорированы.

  • ConcreteComponent - Конкретный компонент:

Является классом целевого объекта который должен быть декорирован.

  • Decorator - Декоратор:

Предоставляет общий интерфейс для объектов-декораторов.

  • ConcreteDecorator  - Конкретный декоратор:

Содержит дополнительную функциональность, которой будет расширяться целевой объект.

Отношения между участниками

Отношения между классами

  • Конкретный класс ConcreteComponent связан связью отношения наследования с абстрактным классом Component.
  • Абстрактный класс Decorator связан связью отношения наследования и связью отношения агрегации с абстрактным классом Component.
  • Конкретные классы ConcreteDecoratorA и ConcreteDecoratorB связанны связью отношения наследования с абстрактным классом Decorator.

Отношения между объектами

  • Объекты типа Decorator (ConcreteDecorator) переадресуют запросы объектам типа Component (ConcreteComponent, ConcreteDecorator) и выполняют дополнительные операции до или после переадресации.

Мотивация

Рассмотрим использование техники декорирования на примере простейшей программы для построения графических интерфейсов. Скажем, программа должна уметь добавлять новое состояние (рамку) или поведение (возможность прокрутки) к элементу управления TextView (TextBox), который отображает текст в окне. По умолчанию TextView не имеет полос прокрутки, поскольку они не всегда нужны. Если полосы прокрутки понадобятся, их можно добавить при помощи декоратора ScrollDecorator. Если понадобится добавить рамку вокруг объекта TextView, ее можно добавить при помощи декоратора BorderDecorator. Также возможно одновременно использовать оба декоратора, тогда отображаемый объект будет иметь и полосы прокрутки, и рамку. На рисунке ниже можно увидеть графическое представление частей результата. 

На диаграмме ниже показан объект класса TextView декорированный объектами классов BorderDecorator и ScrollDecorator

Классы ScrollDecorator и BorderDecorator являются подклассами абстрактного класса Decorator. Класс VisualComponent – это абстрактный класс для представления всех визуальных объектов. 

Классы ScrollDecorator и BorderDecorator могут добавлять любые методы для предоставления необходимой функциональности и использоваться (декорировать) со всеми объектами типа VisualComponent.

 

См. Пример к главе: \009_Decorator\002_Text View 

 

Применимость паттерна

Паттерн Decorator рекомендуется использовать, когда:

 

  • Требуется организовать возможность динамического (во время выполнения) расширения объектов.

 

  • Требуется временно расширить объект новой функциональностью, а позже эту функциональность убрать.

 

 

Результаты

Паттерн Decorator обладает следующими преимуществами:

  • Гибкость.

Гибкость – это свойство программной системы или компонента, позволяющие быстро, легко и безопасно вносить изменения в существующий код или расширять код новой функциональностью. Паттерн Decorator позволяет гибко расширять существующий объект новой функциональностью. Гибкость достигается за счет использования динамических связей отношения, а именно связей отношения агрегации. Паттерн Decorator позволяет добавлять и удалять функциональность во время выполнения программы. Одно и тоже свойство может быть добавлено несколько раз.

Например, можно применить к объекту TextView двойную рамку, для этого нужно просто добавить два декоратора типа BorderDecorator.

  • Необходимая достаточность.

Паттерн Decorator позволяет организовать динамическое добавление новой функциональности объектам по мере необходимости. Вместо того, чтобы пытаться предусмотреть и реализовать в одном классе (ConcreteComponent) всю функциональность которая (может быть?!) возможно понадобится, можно создать простой класс конкретного компонента (ConcreteComponent) и постепенно наращивать функциональность его объектов, с помощью декораторов (ConcreteDecorator). В результате классы не будут содержать неиспользуемые функции, что существенно упростит работу с классом, так как при использовании класса не придется обращать внимания и вникать в работу неиспользуемых методов.

Паттерн Decorator обладает следующими недостатками:

  • Потеря идентичности.

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

Идентичные объекты:

Индивидуальные объекты:

  • Наличие большого числа мелких объектов-декораторов.

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

Реализация

Полезные приемы реализации паттерна Decorator:

  • Соответствие интерфейсов.

Интерфейс декораторов (Decorator) должен соответствовать интерфейсу декорируемого объекта (ConcreteComponent), поэтому, как класс декорируемого объекта, так и классы декораторов должны наследоваться от общего класса (Component).

  • Возможность отсутствия абстрактного класса Decorator.

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

См. пример к главе: \009_Decorator\003_ConcreteDecorator

Известные применения паттерна в .Net

System.Windows.Controls.Decorator

http://msdn.microsoft.com/en-us/library/system.windows.controls.decorator.aspx

System.Data.Entity.Migrations.Infrastructure.MigratorLoggingDecorator

http://msdn.microsoft.com/ru-ru/library/system.data.entity.migrations.infrastructure.migratorloggingdecorator(v=vs.113).aspx

System.Windows.Controls.Primitives.BulletDecorator

http://msdn.microsoft.com/ru-ru/library/system.windows.controls.primitives.bulletdecorator(v=vs.90).aspx

System.Windows.Documents.AdornerDecorator

http://msdn.microsoft.com/en-us/library/system.windows.documents.adornerdecorator.aspx

Microsoft.Windows.Themes.ClassicBorderDecorator

http://msdn.microsoft.com/en-us/library/microsoft.windows.themes.classicborderdecorator.aspx

System.Web.HttpBrowserCapabilitiesWrapper

http://msdn.microsoft.com/ru-ru/library/system.web.httpbrowsercapabilitieswrapper(v=vs.90).aspx

System.Web.HttpApplicationStateWrapper

http://msdn.microsoft.com/ru-ru/library/system.web.httpapplicationstatewrapper(v=vs.90).aspx

System.Web.HttpContextWrapper

http://msdn.microsoft.com/en-us/library/system.web.httpcontextwrapper(v=vs.110).aspx

System.Web.HttpFileCollectionWrapper

http://msdn.microsoft.com/en-us/library/system.web.httpfilecollectionwrapper(v=vs.110).aspx

System.Web.HttpSessionStateWrapper

http://msdn.microsoft.com/en-us/library/system.web.httpsessionstatewrapper(v=vs.110).aspx

© 2017 ITVDN, все права защищены