[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Паттерны. Когнитивный диссонанс
Страницы: 1, 2
McLotos
Всем привет =)
У меня немного рвёт шаблон, он прям трещит по швам.
Вот смотрите есть паттерн Decorator, его суть предельно проста - есть классы, у которых нужно нарастить функционал, не трогая сами классы. Пишем decorator, вызываем в нем декорируемый объект и дальше делаем всё что хотим, например прикручиваем логгер или систему уведомлений, обработчики событий. Я логично подразумевал что интерфейс декоратора должен быть таким же как и у класса, который он декорирует, чтобы можно было если что выкинуть декоратор и использовать чистую реализацию.
И есть паттерн Proxy, который перехватывает запросы к оригинальному объекту и может выполнять какие-то действия до и после вызова реального метода основного объекта. Например логгер, который логирует Request до того как отдать его в класс и логирует ответ до того как выдать его в Response
Логично что для безболезненного внедрения, его интерфейс тоже должен совпадать с интерфейсом проксируемого класса.
Где я тут ошибся? Что у меня не то в логике? Если они одинаковые, то почему называются по-разному? Тот редчайший случай, когда refactoring.guru не внёс ясности в этот вопрос, скорее наоборот =(

_____________
программирование - инструмент для решения конкретных задач, любая попытка спроектировать что-то универсальное приведет к провалу.©paul85
В любом случае тебе прийдётся пройти путь изобретения велосипеда, который прошли другие, только причиной твоего изобретения будет непонимание принципов работы велосипеда изобретённого другими людьми.©SlavaFr
jQuery это попытка использовать АН-225 для перевозки зубочистки
twin
Декоратор изменяет функционал, прокси дополняет. Вот и вся разница. smile.gif

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

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
McLotos
Ну вот например если мне нужно чтобы ответ контроллера был возвращен в json или в xml, в зависимости от header-а запроса, тут применять decorator? а если мне нужно просто добавить логирование, то тут применять proxy?

Получается что к одному классу User extends Controller нужен еще UserDecorator, который применит стратегию JsonResponse или XMLResponse, и нужен еще UserProxy, который будет логировать всё происходящее? Почему-то каждый раз, когда появляется очередной паттерн, количество кода только увеличивается, а ведь раньше просто обходились одним index.php laugh.gif laugh.gif

_____________
программирование - инструмент для решения конкретных задач, любая попытка спроектировать что-то универсальное приведет к провалу.©paul85
В любом случае тебе прийдётся пройти путь изобретения велосипеда, который прошли другие, только причиной твоего изобретения будет непонимание принципов работы велосипеда изобретённого другими людьми.©SlavaFr
jQuery это попытка использовать АН-225 для перевозки зубочистки
twin
Декоратор изменяет методы. Прокси обычно добавляет другие, оставляя нетронутыми методы исходного класса. Хотя это все так размазано,как и все махровое ООП. )))

Кстати, чем больше проходит времени, тем чаще слышится анафема для ООП от опытных, наевшихся этого д... программистов)))

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

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
McLotos
Ну мы все тут знаем как ты не любишь ООП =)
Так в итоге мне что делать? Сделать проксю, которая будет вызывать декоратор а он уже будет стучаться к самому контроллеру? Ну это на случай если я хочу к контроллеру добавить логирование и преобразовывать его ответы в json =)

_____________
программирование - инструмент для решения конкретных задач, любая попытка спроектировать что-то универсальное приведет к провалу.©paul85
В любом случае тебе прийдётся пройти путь изобретения велосипеда, который прошли другие, только причиной твоего изобретения будет непонимание принципов работы велосипеда изобретённого другими людьми.©SlavaFr
jQuery это попытка использовать АН-225 для перевозки зубочистки
twin
Сделай как тебе удобно и обзови хоть горшком. Че так все в эти паттерны уперлись, они же не догма. Получится прокси-декоратор и слава яйцам. smile.gif

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

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
McLotos
Ну собственно мы опять пришли к твоему классическому ответу. twin, ты классный специалист, но твоя нелюбовь к паттернам иногда реально мешает =)
вопрос изначально был не столько в практическом использовании, сколько для понимания ситуации в целом. Вот лично для меня decorator и proxy выглядят одинаковыми, и мне хочется разобраться в чем же они разные и как их вместе использовать. Может я не буду использовать их реально на практике, но понимать их не мешало бы, хотя бы для того чтобы не плеваться когда наткнусь на код очередного бездумного фаната паттернов

_____________
программирование - инструмент для решения конкретных задач, любая попытка спроектировать что-то универсальное приведет к провалу.©paul85
В любом случае тебе прийдётся пройти путь изобретения велосипеда, который прошли другие, только причиной твоего изобретения будет непонимание принципов работы велосипеда изобретённого другими людьми.©SlavaFr
jQuery это попытка использовать АН-225 для перевозки зубочистки
twin
С чего ты взял, что я не люблю паттерны?)))
Это как в анекдоте про грузина.
- Ты памыдоры любищь?
- Кущать любблю, а так - НЭТ!

Как можно их любить или нет... Это же просто паттерны. Я противник того, чтобы все стараться делать на них, потому что это нименуемо ведет к проблемам ООП. Которые приходится разгребать всякими SOLID и иже с ним. НО это дело личное.

Что касается сабжа, я же сказал в чем отличие. Ну на вот кодом:

Вот это прокси:
class Proxy
{
public function getValue()
{
return (new MyClass)->getValue();
}

// Some methods
}


А это декоратор:
class Decorator
{
public function getValue()
{
$value = (new MyClass)->getValue();
return htmlspecialchars($value);
}

// Some methods
}


Их легко можно сложить в один класс и назвать прокси-декоратором. Или деко-прокси. Или горшок. Не важно, это условности. Важно, чтобы было удобно.

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

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
Эли4ка
Цитата (McLotos @ 11.06.2019 - 10:45)
Ну вот например если мне нужно чтобы ответ контроллера был возвращен в json или в xml, в зависимости от header-а запроса, тут применять decorator? а если мне нужно просто добавить логирование, то тут применять proxy?

Мне тоже недавно понадобилось сделать аналогичное. Хочу задать вопрос-разве без прокси или декоратора это не осуществимо? Или сложнее поддерживать код? Или работает хуже?
Guest
Эли4ка
Тут вопрос что первично, курица или яйцо. Если ты сделаешь что то аналогичное, это и будет прокси или декоратор. Другое дело, когда ты изучишь их теоретически, а потом начнёшь притыкать куда ни поподя только потому, что это паттерн и что он где то там описан в GoF..

Как сказал Фаулер, патерны обязательно нужно изучить для того, чтобы знать, где их применять не нужно. smile.gif

Нужно писать не оглядываясь на патерны, а исходя из логики программы, её эффективности, поддерживаемосьи и прозрачности. А паттерн обычно провоцируют делать обратное, опрпадываясь высокими уровнями абстракция, которые по большому счету не просто бесполезны, но и зачастую вредны.
McLotos
Цитата (Эли4ка @ 12.06.2019 - 10:24)
Хочу задать вопрос-разве без прокси или декоратора это не осуществимо? Или сложнее поддерживать код? Или работает хуже?

Осуществимо, если тебе хочется каждый раз править контроллеры, если завтра к json добавится xml. Будешь бегать по всем контроллерам и править? А так можно добавить еще один декоратор и всё будет работать
Цитата (Guest @ 12.06.2019 - 12:52)
Как сказал Фаулер, патерны обязательно нужно изучить для того, чтобы знать, где их применять не нужно. 

Фаулер гений
Цитата (Guest @ 12.06.2019 - 12:52)
Нужно писать не оглядываясь на патерны, а исходя из логики программы, её эффективности, поддерживаемосьи и прозрачности.

Да, тут скорее логика должна быть наоборот. Для решения какой-то проблемы, можно найти паттерн, который поможет ее решить с минимальным затрахом (сорри, но по-другому не скажешь). А не наоборот - когда испольуют паттерны ради паттернов и получают еще больше головной боли. Вот тут я с Мартином согласен =)

_____________
программирование - инструмент для решения конкретных задач, любая попытка спроектировать что-то универсальное приведет к провалу.©paul85
В любом случае тебе прийдётся пройти путь изобретения велосипеда, который прошли другие, только причиной твоего изобретения будет непонимание принципов работы велосипеда изобретённого другими людьми.©SlavaFr
jQuery это попытка использовать АН-225 для перевозки зубочистки
Эли4ка
Цитата (McLotos @ 12.06.2019 - 12:12)
Осуществимо, если тебе хочется каждый раз править контроллеры, если завтра к json добавится xml. Будешь бегать по всем контроллерам и править? А так можно добавить еще один декоратор и всё будет работать

Это как часто нужно менять структуру выдачи ответа в json чтобы ради этого делать декоратор?
Сделал json, xml ответы и забыл. Обновилось API - добавил новые поля.
json, xml это не те вещи, где нужно применять декоратор и уж тем более прокси.
twin
Цитата (McLotos @ 12.06.2019 - 09:12)
Осуществимо, если тебе хочется каждый раз править контроллеры, если завтра к json добавится xml.

А если не добавится? smile.gif Что кстати скорее всего.

Так что прежде чем изучать паттерны, изучи антипаттерны. Фаулер не зря это изрек.
В твоем случае это похоже на "золотой дождь молоток", а так же прямое нарушение YAGNI.

Ты сам уже заметил, что
Цитата (McLotos @ 11.06.2019 - 07:45)
Почему-то каждый раз, когда появляется очередной паттерн, количество кода только увеличивается,


Подумай хорошенько, сколько тебе потребуется времени, чтобы добавить новый формат и сколько вообще есть таких форматов. У тебя овер 1000100 контроллеров?

И с удивлением заметишь, что время, потраченное тобой в попытках применить универсальное решение, потому что ты где-то краем уха слышал про паттерны, намного превышает время таких правок.

Тем более что
1. Вероятность смены формата обычно стремится к нулю.
2. Какого хрена вообще выбором формата занимается контроллер?

Ты бы лучше подумал бы об архитектуре, а не пытался залатать дыры ООП костылями в виде этих паттернов, которые именно для латания дыр и придуманы.

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

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

Нужно уважать мнение оппонета. Ведь заблуждаться - его святое право.

Настаивал, настаиваю и буду настаивать на своем. На кедровых орешках.

user posted image
Arh
McLotos
Я их всех врапперами называю)
А разница у них как я понимаю только в теоретической части. Это как сказать "насыпь 100 грамм" или "налей сто грамм", оба варианта означают что надо из одной тары в другую переместить 100 грамм, но при этом уточняют более конкретно.

Задача прокси - перенаправлять запросы. Можно в прокси навешать логгеров и много чего ещё, но это не его основная задача.
Пример 1: есть библиотека у которой методы называются не в стиле твоего приложения, можно обернуть её в прокси и переименовать методы. будешь обращаться к $vasyaProxy->getViews() вместо $vasya->give_me_views_ёpte()
Пример 2: есть библиотека у которой скрыты свойства, а тебе они нужны, вместо того что бы каждый раз рефлексией смотреть в этот класс, ты пишешь эту логику один раз в прокси.
Пример 3: есть библиотека, которая делает добро, ты не хочешь что бы все подряд могли получить добро на халяву, делаешь прокси в котором проверяешь что за добром пришли с разрешённого ip.
Пример 4: есть библиотека, которая часто обновляется и автор постоянно методы переименовывает, меняет количество и места аргументов. Делаешь прокси со стабильным интерфейсом и горя не знаешь.
Пример 5: есть библиотека, ты хочешь палить кто там какой пароль вводит, делаешь прокси, проксируешь, тыришь данные, логгируешь это всё себе в заначку.
Пример 6: есть несколько библиотек, которые переводят тексты. Одна переводит с гугла, другая с яндекса, у каждой лимит, делаешь прокси который рандомно подключает библиотеки, тем самым балансирую между ними, удваивая лимит, утраивая лимит итд, всё через один интерфейс.

То есть в прокси ты не менял данные. Ты их украл, ты поменял интерфейсы, сделал балансировщик, но данные проксировал как есть.

У декоратора задача добавить новый функционал или поменять старый. Это такая же обёртка как прокси, но делает другие вещи.
Пример 1: есть библиотека, которая отправляет почту, тебе надо что бы матерные слова вырезались, делаешь декоратор, который вырезает мат из текста перед отправкой в библиотеку почты.
Пример 2: есть библиотека, которая загружает файлы и возвращает тип, размер, где лежат файл итд, но не возвращает хэш файла, делаешь декоратор.
Пример 3: есть библиотека, которая загружает файлы но не умеет их удалять, делаешь декоратор, в который добавляешь новый метод.
Пример 4: есть библиотека у который 100 методов, а тебе нужны только 5 и ты не хочешь что бы другими пользовались потому что они не нужны и ты их в доке даже не описывал. Делаешь декоратор, где только 5 методов.

То есть декоратор он почти как прокси, но может данные поменять, может добавить нового функционала, может порезать старый, может упростить/усложнить интерфейс.

Наверное можно мои пункты по други паттернам разложить, сериализеры, валидаторы итд. Я где то натыкался что декоратор это просто более высокий уровень абстракции чем прокси. Как враппер более абстрактный чем декоратор. Но я бы не стал называть декоратором то, у чего идея классического перенаправления данных, декоратор для меня это типа наследования, где ты можешь всю логику переделать, все данные перевернуть.

Пример с переводчиками, есть библиотека, которая возвращает данные, есть декоратор, который переводит через яндекс, есть другой, который переводит через гугл, и есть прокси, который балансирует декораторами. Вот так прокси->декоратор1/2 ->библиотека


_____________
Промокод предоставляет скидку на заказ домена и/или хостинга reg.ru
BFCC-3895-8804-9ED2
Ron
Давненько ничего не постил, так что всех приветствую! =)

Цитата (McLotos @ 11.06.2019 - 11:13)
Где я тут ошибся? Что у меня не то в логике?

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

"Единичный" дектоатор структурно ничем не отличается от прокси. Разница чисто формальная, на тему чего можно холиварить, если есть желание (читай нечего делать). Тут станет предельно понятно из контекста и нет смысла придираться. Например: "я сделал сортировку/фильтр данных через прокси" или "я сделал сортировку/фильтр данных через декоратор". Смысл по сути один и тот же, только во втором случае скорее всего на ум придет какая-то сложная сортировка многоэтапная, которая может зависеть (и скорее всего) от внешних факторов, допустим от UI. Тут важно другое. Тебя собеседник поймет и так и сяк, а значит цель достигнута. В конце концов не в названиях дело, тем более столь родственных по структуре паттернов.

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

Цитата (McLotos @ 12.06.2019 - 13:12)
Осуществимо, если тебе хочется каждый раз править контроллеры, если завтра к json добавится xml.

В местах где вероятно появление ветвления, но пока его нет, достаточно просто объявить интерфейс. И YAGNI не будет нарушен в случае чего, и в будущем с расширением не будет проблем. Есть даже мнение, что интерфейсы нужно объявлять вообще всем классам, но я по правде не сторонник. Возможно сие стремление уходит корнями в С++, если понимаете о чем я.

Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.