Шаблоны программирования. Decorator.

Еще один довольно гибкий шаблон, о котором стоит поговорить – Decorator. Он отлично показывает насколько композиция может быть мощнее наследования.

Давайте сразу к примеру. Пусть мы программируем задачу по производству игрушек. Игрушки могут быть разные и цвета их могут быть различными. Очевидно, если мы создадим абстрактный класс игрушек и начнем производство шариков. Будет примерно следующее:

 

В итоге вроде бы неплохо. Но вот только представьте. А что если нам нужно будет делать шары не только синего цвета? Что если нам потребуется делать их еще и красные, а может быть и смешанных цветов? Представьте себе как разрастется структура наследования, если появятся классы BlueRedBall и т.д. Страшно представить.

Но ничего. Для этого у нас есть шаблон Decorator. Основная его суть проста: получается что-то вроде матрешки. Методы реализованные в корневом элементе (шарик) переопределяются в накладываемых на элемент классах (шарик становится сперва синим, потом красным, в итоге он сине-красный). Сложновато на слух, но пример поможет разобраться:

 

Итак, имеем все тот же абстрактный Item и класс Balloon. Но вот структура далее изменилась. Абстрактный класс ItemDecor имеет свойство $item, которое содержит ссылку на объект типа Item. В этом же классе имеется и конструктор, который эту ссылку создает. Кстати, класс ItemDecor так же абстрактный, так ка наследует Item, но не реализует getcolor().

Далее имеем классы цветов, но вот наследуются они от ItemDecor и реализуют метод getcolor. В этом методе они получают из свойства-ссылки массив цветов (изначально в массиве шарика стоит ноль, обусловим это бесцветностью), а затем модифицируют этот массив и выдают уже измененную версию (ну у нас это просто добавление в массив цвета, условного конечно).

В итоге получается что-то вроде конвейера, когда вызываем методы getcolor. Это видно в примере использования. Там мы создаем сине-красный шарик. Очевидно, что методы будут вызываться из “глубины” создания объекта. Поэтому сначала шарик станет бесцветным от класс Ballon, потом синим, а потом красным. Именно в таком порядке цвета расположатся в массиве. Можете скопировать код и проверить.

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

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

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">