Декоратор

Шаблон оформления декоратора

Намерение

  • Добавляйте дополнительные обязанности к объекту динамически. Декораторы предоставляют гибкую альтернативу подклассам для расширения функциональности.
  • Указанное клиентом украшение основного объекта путем его рекурсивного обертывания.
  • Упаковка подарка в коробку и упаковка в коробку.

Проблема

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

Обсуждение

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

Но шаблон Decorator предлагает дать клиенту возможность указать любую комбинацию «функций», которую он желает.

Виджет *  aWidget  =  new  BorderDecorator ( новый HorizontalScrollBarDecorator ( новый VerticalScrollBarDecorator ( новое окно ( 80 , 24 ) ) ) ) ; aWidget -> draw ( ) ;
   
     
          

Этой гибкости можно достичь с помощью следующего дизайна

Другой пример каскадного (или сцепления) функций вместе для создания настраиваемого объекта может выглядеть так …

Stream *  aStream  =  новый  CompressingStream ( новый ASCII7Stream ( новый FileStream ( "fileName.dat" ) ) ) ; aStream -> putString ( "Привет, мир" ) ;
   
     
  

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

Обратите внимание, что этот шаблон позволяет добавлять обязанности к объекту, а не методы к интерфейсу объекта. Интерфейс, представленный клиенту, должен оставаться постоянным при указании последовательных уровней.

Также обратите внимание, что идентичность основного объекта теперь «спрятана» внутри объекта декоратора. Попытка получить прямой доступ к основному объекту теперь является проблемой.

Состав

Клиент всегда заинтересован CoreFunctionality.doThis(). Клиент может, или не может, быть заинтересованы в OptionalOne.doThis() и OptionalTwo.doThis(). Каждый из этих классов всегда делегирует базовый класс Decorator, и этот класс всегда делегирует содержащийся объект “wrappee”.

пример

Декоратор динамически прикрепляет к объекту дополнительные обязанности. Орнаменты, которые добавляют на сосны или ели, являются примерами декораторов. К дереву можно добавить огоньки, гирлянды, леденцы, стеклянные украшения и т. Д., Чтобы придать ему праздничный вид. Орнаменты не меняют саму елку, которая распознается как рождественская елка, независимо от того, какие украшения используются. В качестве примера дополнительной функциональности добавление лампочек позволяет «зажечь» елку.

Другой пример: штурмовое орудие само по себе является смертельным оружием. Но вы можете применить определенные «украшения», чтобы сделать его более точным, бесшумным и разрушительным.

Контрольный список

  1. Убедитесь, что контекст: один основной (или необязательный) компонент, несколько дополнительных украшений или оберток и общий для всех интерфейс.
  2. Создайте интерфейс «Наименьший общий знаменатель», который сделает все классы взаимозаменяемыми.
  3. Создайте базовый класс второго уровня (Decorator) для поддержки дополнительных классов-оболочек.
  4. Класс Core и класс Decorator наследуются от интерфейса LCD.
  5. Класс Decorator объявляет отношение композиции к интерфейсу LCD, и этот член данных инициализируется в его конструкторе.
  6. Класс Decorator делегирует объекту LCD.
  7. Определите производный класс Decorator для каждого дополнительного украшения.
  8. Производные классы Decorator реализуют свои функции оболочки и делегируют базовый класс Decorator.
  9. Клиент настраивает тип и порядок объектов Core и Decorator.

Эмпирические правила

  • Адаптер предоставляет другой интерфейс для своей темы. Прокси-сервер предоставляет тот же интерфейс. Decorator предоставляет улучшенный интерфейс.
  • Адаптер изменяет интерфейс объекта, декоратор расширяет обязанности объекта. Таким образом, декоратор более прозрачен для клиента. Как следствие, Decorator поддерживает рекурсивную композицию, что невозможно с чистыми адаптерами.
  • Composite и Decorator имеют похожие структурные схемы, что отражает тот факт, что оба используют рекурсивную композицию для организации неограниченного числа объектов.
  • Декоратор можно рассматривать как вырожденный композит только с одним компонентом. Однако декоратор добавляет дополнительные обязанности – он не предназначен для агрегирования объектов.
  • Декоратор разработан, чтобы вы могли добавлять обязанности к объектам без создания подклассов. Composite фокусируется не на украшении, а на представлении. Эти намерения различны, но дополняют друг друга. Следовательно, Composite и Decorator часто используются вместе.
  • Composite может использовать Chain of Responsibility, чтобы позволить компонентам получать доступ к глобальным свойствам через их родительский элемент. Он также может использовать Decorator для переопределения этих свойств в частях композиции.
  • Декоратор и Прокси имеют разные цели, но похожую структуру. Оба описывают, как обеспечить уровень косвенного обращения к другому объекту, а реализации сохраняют ссылку на объект, которому они направляют запросы.
  • Декоратор позволяет вам изменить скин объекта. Стратегия позволяет изменить кишки.

Design pattern

Добавить комментарий

Ваш адрес email не будет опубликован.