Страницы

Поиск по вопросам

понедельник, 8 июля 2019 г.

proxy vs decorator

Доброго времени суток. В своем вопросе рассматриваю паттерны прокси и декоратор исключительно в контексте языка c++. Вопрос таков: в чем различия между паттерном proxy и паттерном decorator?
из исследованного:
PROXY:
Заместитель (англ. Proxy) — структурный шаблон проектирования, который предоставляет объект, который контролирует доступ к другому объекту, перехватывая все вызовы (выполняет функцию контейнера).(https://ru.wikipedia.org/wiki/Proxy_(%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F)) Идея паттерна «Заместитель» заключается в предоставлении клиенту другого объекта (заместителя), взамен объекту с контролируемым доступом. При этом, объект-заместитель, реализует тот-же интерфейс, что и оригинальный объект, в результате чего, поведение клиента не требует изменений. Иными словами, клиент взаимодействует с заместителем ровно как с оригинальным объектом посредством единого интерфейса. Клиент, так же, не делает предположений о том работает ли он с реальным объектом или его заместителем. Контролирование доступа к объекту, при этом, достигается за счет использования ссылки на него в заместителе, благодаря которой заместитель переадресовывает внешние вызовы контролируемому объекту, возможно сопровождая их дополнительными операциями.(https://habrahabr.ru/post/88722/) Здесь(https://www.codeproject.com/Articles/186001/Proxy-Design-Pattern) тоже указано, что целью прокси является защита скрываемого объекта.
===
DECORATOR
Декоратор (англ. Decorator) — структурный шаблон проектирования, предназначенный для динамического подключения дополнительного поведения к объекту. Шаблон Декоратор предоставляет гибкую альтернативу практике создания подклассов с целью расширения функциональности.( https://ru.wikipedia.org/wiki/%D0%94%D0%B5%D0%BA%D0%BE%D1%80%D0%B0%D1%82%D0%BE%D1%80_(%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F) ) Паттерн Декоратор: Добавляет дополнительные возможности к объекту динамически. Декораторы предоставляют гибкую альтернативу наследованию для расширения функциональности.(https://habrahabr.ru/post/212641/ ) Здесь(https://sourcemaking.com/design_patterns/decorator) так же указано, что мы хотим добавить дополнительный функционал к объекту, не изменяя сам объект.
===
Хорошо. А теперь - чем же они, в своей сути, отличаются? Контроль доступа к объекту разве не является дополнительным функционалом? Вики отвечает, что декоратор "предоставляет расширенный интерфейс". Но в чем его расширенность? и по условию использования прокси мы тоже можем "вешать" доп.действия на нужный метод(например, вставлять логирование, подсчитывать количество пользователей объекта - привет тебе, смартпойнтер☺ и так далее). Схема работы у них тоже примерно одна и та же, мало того -
"Классический паттерн Декоратор содержит родительский абстрактный класс Component, который объявляет некоторые общие операции для других конкретных компонентов. Абстрактный класс Component может быть обернут в другой класс Decorator. Decorator содержит ссылку на другой Component. ConcreteDecorator определяет некоторое расширенное поведение для других похожих Component-ов и Decorator-ов и выполняет операцию включенного в него объекта Component. "
Как понял(сейчас пишу мое понимание вопроса, оно может быть ошибочным), патттерн прокси имеет почти такую же структуру, как и классический декоратор(и что есть "неклассический" декоратор?), единственно - он требует что б был один интерфейс, от которого наследовались объект прокси и тот объект, который мы используем. Но разве это существенно? К тому же, если мы используем паттерн прокси, например, для доступа к api какого-нибудь сайта, то нам не нужно api этого сайта наследовать от своего интерфейса. Так чем же различаются эти два паттерна? не зря же они называются по-разному?


Ответ

Отличия в том, что Заместитель добавляет функционал в реализацию не изменяя интерфейс, а Декоратор добавляет функционал расширяя интерфейс. В первом случае, клиент работает как обычно, наличие Заместителя для него скрыто. Во втором случае, клиент либо изначально ожидает расширенный интерфейс, либо может менять свое поведение в зависимости от "расширенности" интерфейса. Тут факт расширения скрыт скорее от обработчика интерфейса.
Заместитель может, например, выполнять журналирование вызовов функций интерфейса. Либо маршалинг, то есть передачу вызовом функций по сети, прозрачно для клиента.
Декораторы обычно применяют при разработке графического интерфейса пользователя. Хороший пример - рамки окон, они могут быть не просто разных цветов и форм, а добавлять новое поведение объекту. При этом декоратор здесь нужен для управления эти дополнительным поведением.

Комментариев нет:

Отправить комментарий