Объяснение шаблона декоратора в GoF сбивает с толку (или просто неправильно) - PullRequest
4 голосов
/ 14 октября 2010

Я перебираю некоторые вопросы о шаблонах проектирования и рассмотрел определение и примеры шаблона Decorator в GoF.Там написано:

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

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

NetObjectives допускает ту же ошибку:

http://www.netobjectives.com/PatternRepository/index.php?title=TheDecoratorPattern

Обсуждение Декоратора репозитория паттернов в Портленде показывает, что существует путаница в том, что является декоратором, а что нет.

http://c2.com/cgi/wiki?DecoratorPattern

ВикипедияИмеет некоторый смысл этого противоречия, отмечая, что делегат внутри Decorator должен быть установлен во время построения (другие методы DI также будут работать)

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

Все примеры шаблона Decorator (в Java или C ++) требуется статическая конструкция либо через наследование, либо путем реализации интерфейса.Объяснение в GoF говорит, что дополнительные обязанности, однако, устанавливаются динамически.Но это просто неправильно.

Комментарии в PPR говорят о динамических языках, которые могут добавлять методы во время выполнения, но Java и C ++ не являются динамическими, и в объяснении Decorator не говорится, что он ограничен динамическими языками, такими какGroovy и Lisp.

Разве правильное объяснение Decorator не говорит о том, что в языках, которые не поддерживают создание динамических методов, участвуют как статические, так и динамические конструкции?

Объяснение GoF просто неверно, так какпоказано на собственных примерах, или я что-то не так понял?

Ответы [ 2 ]

6 голосов
/ 14 октября 2010

Динамический Я думаю, что слово «динамический» стало означать нечто иное, чем когда GOF написал книгу.Я предполагаю, что они намеревались сказать «добавление до / пост-поведения к объекту без фактического изменения кода / определения базового объекта».Для клиентов объект (оформленный или нет) выглядит одинаково.Сегодня динамическое связывается с динамическими языками и в этом смысле означает свободную типизацию и возможность добавлять методы / поведение к объекту во время выполнения.

Альтернатива подклассам

Шаблон декоратора является альтернативой подклассам.Подклассы добавляют поведение во время компиляции, и изменение влияет на все экземпляры исходного класса;Декорирование может обеспечить новое поведение во время выполнения для отдельных объектов.

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

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

var dao = new PerformanceTrackingDecorator(new TurboSpeedDecorator(SqlDataAccessObject))
// use dao and later..
dao = new PerformanceTrackingDecorator(new TurboSpeedDecorator(XmlDataAccessObject))
//at runtime, I've added certain behavior to Sql and Xml DAOs
0 голосов
/ 15 октября 2010

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

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

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

В динамическом языке, таком как Lisp или Groovy, я думаю, вы могли бы просто объединить логику декорирования в логику draw () самого класса.Требование соответствия интерфейса не было бы необходимым, и при этом не было бы необходимости иметь отдельные классы для декорированного объекта и Decorator.

Я собираюсь добавить изучение Lisp в свой Bucket List, чтобы я мог видеть, как шаблоны проектированияизменить на динамическом языке.

...