Спасибо что услышал мое предложение по использованию примеров при объяснении паттернов. Время от времени пересматриваю для закрепления в голове и незабывания, вроде патерны знаешь но насколько же всё-таки приятно смотреть с примерами :) хотения и терпения тебе
Очень много кода. Я понимаю, что это характерно для данного шаблона, но всегда подмывает пойти более простым пусть и не совсем правильным путем и решить все просто при помощи большого количества условий)
Спасибо! Классное видео! По поводу интриги у меня два предположения: 1. Возможно что-то не то с методом actionMain(), который в свою очередь запускает метод run() декораторов и основного декорируемого класса. У меня получилась такая несимметричная матрёшка, когда я переопределил методы actionBefore, actionMain и actionAfter во всех декораторах: [2021-03-28 16:14:36] local.INFO: Decorator [2021-03-28 16:14:36] local.INFO: Notify managers before [2021-03-28 16:14:36] local.INFO: Notify managers immediately before calling run() action [2021-03-28 16:14:36] local.INFO: Notify users before [2021-03-28 16:14:36] local.INFO: Notify users immediately before calling run() action [2021-03-28 16:14:36] local.INFO: Log Before [2021-03-28 16:14:36] local.INFO: Log immediately before calling run() action [2021-03-28 16:14:36] local.INFO: Base update [2021-03-28 16:14:36] local.INFO: Log After [2021-03-28 16:14:36] local.INFO: Notify users after [2021-03-28 16:14:36] local.INFO: Notify managers after Не скажу, что это прям ошибка, но если бы сообщения с "run()" были бы рядом с "Base update", было бы красивее:) 2. Возможно что-то с наследованием? У Вас свернута папочка "Inheritance" в каталоге с паттерном и Вы не показывали, что в ней:))
Большая просьба в видео раскрывать в дереве проекта те папки в которых лежат файлы. Поможет определить общий объем темы, сколько классов будет создано, сколько интерфейсов и т.д.
а почему вы не показываете все новые файлы?; например: Order.php, OrderUpdateDecoratorNotifierUsers.php... подразумевается, что они пустые, или их надо самим дописать...? // также скрытые юзы приводят к не всегда очевидным ошибкам...
1. Классное видео -- посмотрю предыдущие. 2. С ошибкой -- интгрига ...! ) Круто У меня вот есть вопрос к АбстрактДекоратору, а именно: - разбиение обертки на actionBefore, mainAction, actionAfter конечно, экономит на расширении декораторов, но оно провоцирует на добавление в декоратор мутируемого состояния: в actionBefore что-то считаем, записываем в контекст (он же this), потом в mainAction -- это читаем, принимаем решения тоже что-то считаем и тоже скорее всего что-то запишем, чтобы потом в actionAfter что-то вывести. Хотя по факту, если бы мы все сделали в переопределенном методе run, то контекст бы не понадобился. Я не о том, что все надо писать в одном методе, -- конечно же, внутри конерктного декоратора все надо декомпозировать в соответствии с его семантикой так, чтобы переопределенный метод run было легко прочитать. Сейчас это все выглядит, как экономия на "this->decoratedObject->run($order, $orderData)". В итоге все выльется, либо в то, что наследники будут переопределять mainAction точно так же, как они бы переопределяли сам метод run (тогда почему бы так не сделать сразу), либо будет использоваться мутрируемое состояние экземпляра декоратора, либо ... и то, и другое сразу. Лучше в абстрактном декораторе ограничиться только конструктором. И да, определения в англоязыной вики немного другие -- имеет смысл их тоже принимать во внимание.
Уффф...последние три паттерна, смысл то понятен. Словами на котиках могу объяснить и даже словами на примерах из реальных кейсов разработки. Но написать самому код...не смогу, все-таки опыта пока не хватает.
На примере какой нить игры, где нужно сотне разных противников под общим интерфейсом добавить какое то поведение, очень накладно создавать еще 100 подклассов для добавления строчки кода
Немного непонятное описание потому что на ум сразу приходит Стратегия а не Декоратор Мы же должны расширить метод какого-то объедка а не просто объедок. А в описании вроде основная цель поцепить новое поведение конкретно объдку
@@DmitryAfanasyev ну, получилось, что так. Кстати, не думал замутить подкаст не с уроками, а где будешь приглашать гостей поговорить про код и программирование?
В глаза бросаются две проблемы 1) $orderData передаётся массивом, целостность массива ничем не гарантируется, нужен какой-то вэлуе обжект или dtо (кстати можно отдельное видео сделать и в нём объединить простой патерн DTO и как его правильно использовать в ларавеле и передавать между слоями и так далее. Есть интересное видео по использованию DTО в symfony, но там на аннотациях завязано, так бесит...) 2) в конфиге нет порядка выполнения, кто-то случайно поменяет порядок или вставит свою запись где-то в верх или в середину и вся логика декоратора пойдёт по бороде. Надо вводить жёсткий порядок выполнения и сортировать коллекцию по этому порядку а уже потом производить все эти декорирования.
@@DmitryAfanasyev 1. Попытаюсь объяснить своими словами: ДТО полностью ломают инкапсуляцию, т к являются просто контейнерами данных и позволяют им(данным) свободно утекать в другие части программы. Они не самодостаточны 2. Синглтон антипаттерн, и поэтому мы не должны его использовать. Его следует знать как то, что необходимо избегать
@@DmitryAfanasyev Почему не надо? а если нужно тест написать? Неймспейсы выше - это дичь, поскольку пользователи конфига могут не знать такую особенность, могут тупо забыть, лучше прописывать полностью в конфиге
@@DmitryAfanasyev а, то есть вверху кофига? тогда да, норм. не увидел в видосе, где именно use используется. поэтому и спросил про репу, чтобы более наглядно видеть код.
самая большая проблема с порядком выполнения. В вашем примере нельзя просто сначала например залогироватьДО, потом написать юзеру, потом залогировать после, если мы делаем что-то типа $logger($user($entity)) проблема №2, как по мне прекрасно описана в том же рефакториг гуру, где он описывал read/write данных. Там если не знать, какой цепочкой данные в декоратор собрались(допустим, что это красиво настраивается через UI гдето, и, внезапно, программистский баг, и таблица настроек слетает), непонятно будет, как потом исходный поток байт развернуть. И опять же, проблема 1, надо в нужной последовательности развернуть данные
Мне кажется использовать методом стека может быть не оптимально! Лучше написать каждый декоратор под свою задачу, при создании декоратора передавая параметры объектов к примеру "logger"... если это нужно.
Как вам шаблон, коллеги? Видео, кстати, теперь и в 2К доступно.
Как и все шаблоны со своим приколом)
Спасибо что услышал мое предложение по использованию примеров при объяснении паттернов. Время от времени пересматриваю для закрепления в голове и незабывания, вроде патерны знаешь но насколько же всё-таки приятно смотреть с примерами :) хотения и терпения тебе
Очень много кода. Я понимаю, что это характерно для данного шаблона, но всегда подмывает пойти более простым пусть и не совсем правильным путем и решить все просто при помощи большого количества условий)
Дмитрий, добрый день. Можете сделать актуальное видео по работе с WebSocket-ами?
Возьму на заметку 👍
Вот это заморочился, спасибо, было интересно и полезно)
Дмитрий, спасибо вам за вашу работу
🙏
Спасибо огромное ! Все понятно - и по полочкам разложено !
Спасибо! Классное видео!
По поводу интриги у меня два предположения:
1. Возможно что-то не то с методом actionMain(), который в свою очередь запускает метод run() декораторов и основного декорируемого класса. У меня получилась такая несимметричная матрёшка, когда я переопределил методы actionBefore, actionMain и actionAfter во всех декораторах:
[2021-03-28 16:14:36] local.INFO: Decorator
[2021-03-28 16:14:36] local.INFO: Notify managers before
[2021-03-28 16:14:36] local.INFO: Notify managers immediately before calling run() action
[2021-03-28 16:14:36] local.INFO: Notify users before
[2021-03-28 16:14:36] local.INFO: Notify users immediately before calling run() action
[2021-03-28 16:14:36] local.INFO: Log Before
[2021-03-28 16:14:36] local.INFO: Log immediately before calling run() action
[2021-03-28 16:14:36] local.INFO: Base update
[2021-03-28 16:14:36] local.INFO: Log After
[2021-03-28 16:14:36] local.INFO: Notify users after
[2021-03-28 16:14:36] local.INFO: Notify managers after
Не скажу, что это прям ошибка, но если бы сообщения с "run()" были бы рядом с "Base update", было бы красивее:)
2. Возможно что-то с наследованием? У Вас свернута папочка "Inheritance" в каталоге с паттерном и Вы не показывали, что в ней:))
Дмитрий крут!
А чем этот декоратор отличается например от реализации в typescript или java? @decorator
Хорошая подача
спасибо за твои видео!
Я пришел с курса Эксперn PHP, почти закончил, видимо поверил в себя! Ребята старый смарти рулит!
спасибо за видео
Большая просьба в видео раскрывать в дереве проекта те папки в которых лежат файлы. Поможет определить общий объем темы, сколько классов будет создано, сколько интерфейсов и т.д.
Да вроде всегда показываю всю используемую иерархию...
Спасибо за Вашу работу! Смотрится легко. Вопрос: планируете ли Вы добавить в курс "Laravel" аутентификацию и авторизацию пользователей?
Будет отдельным миникурсом
а почему вы не показываете все новые файлы?; например: Order.php, OrderUpdateDecoratorNotifierUsers.php...
подразумевается, что они пустые, или их надо самим дописать...?
// также скрытые юзы приводят к не всегда очевидным ошибкам...
Странно, полагаю такого быть ге может. Всегда все полностью показывал и по нескольку раз. Гляну что в видео...
1. Классное видео -- посмотрю предыдущие.
2. С ошибкой -- интгрига ...! ) Круто
У меня вот есть вопрос к АбстрактДекоратору, а именно:
- разбиение обертки на actionBefore, mainAction, actionAfter конечно, экономит на расширении декораторов, но оно провоцирует на добавление в декоратор мутируемого состояния: в actionBefore что-то считаем, записываем в контекст (он же this), потом в mainAction -- это читаем, принимаем решения тоже что-то считаем и тоже скорее всего что-то запишем, чтобы потом в actionAfter что-то вывести. Хотя по факту, если бы мы все сделали в переопределенном методе run, то контекст бы не понадобился. Я не о том, что все надо писать в одном методе, -- конечно же, внутри конерктного декоратора все надо декомпозировать в соответствии с его семантикой так, чтобы переопределенный метод run было легко прочитать. Сейчас это все выглядит, как экономия на "this->decoratedObject->run($order, $orderData)". В итоге все выльется, либо в то, что наследники будут переопределять mainAction точно так же, как они бы переопределяли сам метод run (тогда почему бы так не сделать сразу), либо будет использоваться мутрируемое состояние экземпляра декоратора, либо ... и то, и другое сразу.
Лучше в абстрактном декораторе ограничиться только конструктором.
И да, определения в англоязыной вики немного другие -- имеет смысл их тоже принимать во внимание.
так что за ошибка то была в итоге?
Уффф...последние три паттерна, смысл то понятен. Словами на котиках могу объяснить и даже словами на примерах из реальных кейсов разработки. Но написать самому код...не смогу, все-таки опыта пока не хватает.
На примере какой нить игры, где нужно сотне разных противников под общим интерфейсом добавить какое то поведение, очень накладно создавать еще 100 подклассов для добавления строчки кода
вот-вот, для других целей, они и не нужны
Великолепный паттерн, надёжный, блять, как швейцарские часы
Не туда написал, это к компоновщику
Прочел голосом Гоблина 😁
@@DmitryAfanasyev написал голосом Гоблина
Thank You!
А можно где то взять этот код, что б самому посмотреть?
Код не выкладываю. Вредит обучению. Надо руками набирать самому.
будут ли примеры взаимодействие с Vue?
Да
Немного непонятное описание потому что на ум сразу приходит Стратегия а не Декоратор
Мы же должны расширить метод какого-то объедка а не просто объедок.
А в описании вроде основная цель поцепить новое поведение конкретно объдку
Интрига заключалась как раз в дто?) Думаю, стоит записать видосы про дто вэлью обжект и основы ооп
Нет, не в дто
@@DmitryAfanasyev ну, получилось, что так. Кстати, не думал замутить подкаст не с уроками, а где будешь приглашать гостей поговорить про код и программирование?
Типа айтиБорода? Не думал о таком формате.
@@DmitryAfanasyev ну, более неофициально. Собираются челы и говорят о чем-то. Можно по темам или просто об айти в целом. Как пойдет
В глаза бросаются две проблемы
1) $orderData передаётся массивом, целостность массива ничем не гарантируется, нужен какой-то вэлуе обжект или dtо (кстати можно отдельное видео сделать и в нём объединить простой патерн DTO и как его правильно использовать в ларавеле и передавать между слоями и так далее. Есть интересное видео по использованию DTО в symfony, но там на аннотациях завязано, так бесит...)
2) в конфиге нет порядка выполнения, кто-то случайно поменяет порядок или вставит свою запись где-то в верх или в середину и вся логика декоратора пойдёт по бороде.
Надо вводить жёсткий порядок выполнения и сортировать коллекцию по этому порядку а уже потом производить все эти декорирования.
DTO это анти-паттерн
1) почему? Пруфлинк в студию 2) синглтон антипаттерн, и?.
@@DmitryAfanasyev 1. Попытаюсь объяснить своими словами: ДТО полностью ломают инкапсуляцию, т к являются просто контейнерами данных и позволяют им(данным) свободно утекать в другие части программы. Они не самодостаточны
2. Синглтон антипаттерн, и поэтому мы не должны его использовать. Его следует знать как то, что необходимо избегать
Надо Тейлору написать, а он в ларавеле внедрил и оптимизировал создание синглтонов. Не разбирается наверное в шаблонах.
Про дто не понял объяснения.
Есть ли какая-то репа с кодом уроков?
Отсутствует
@@DmitryAfanasyev печально
Возникли два вопроса:
1. как в декоратор прокинуть объект логера?
2. почему ты в конфиге прописал классы без нэймспейсов?
В ларе ведь логгер из коробки - не надо прокидывать. Неймспейсы выше в секции use.
@@DmitryAfanasyev Почему не надо? а если нужно тест написать? Неймспейсы выше - это дичь, поскольку пользователи конфига могут не знать такую особенность, могут тупо забыть, лучше прописывать полностью в конфиге
Напиши Тейлору про дичь нэймспейсов, а то он их тоже в конфигах вверху херачит.
@@DmitryAfanasyev а, то есть вверху кофига? тогда да, норм. не увидел в видосе, где именно use используется. поэтому и спросил про репу, чтобы более наглядно видеть код.
самая большая проблема с порядком выполнения. В вашем примере нельзя просто сначала например залогироватьДО, потом написать юзеру, потом залогировать после, если мы делаем что-то типа $logger($user($entity))
проблема №2, как по мне прекрасно описана в том же рефакториг гуру, где он описывал read/write данных. Там если не знать, какой цепочкой данные в декоратор собрались(допустим, что это красиво настраивается через UI гдето, и, внезапно, программистский баг, и таблица настроек слетает), непонятно будет, как потом исходный поток байт развернуть. И опять же, проблема 1, надо в нужной последовательности развернуть данные
Мне кажется использовать методом стека может быть не оптимально!
Лучше написать каждый декоратор под свою задачу, при создании декоратора передавая параметры объектов к примеру "logger"... если это нужно.
Не плохо, но как то криповато получается вложенность, new в new в new ... похоже на callback hell
Так и есть. Можно неплохо так усложнить код.
я в своё время, как только начинал учить патерны, видел такую реализацию: $order = new Sugar(new Sugar(new Coffee()));
Роберт Мартин против такого.
Лол в питоне и с# это делать проще