Вот такие подстрочники по книжке очень интересны. Сколько было битв на моей практике с использованием DTO... Когда проект с глубокими корнями, где бизнес-логика крепко сидит в методах модели, уже до лампочки эстетика, принципы, культура итп. Спасибо за выпуск, ликбез полезный.
Dependency Injection - тема одновременно и простая, и сложная. Важная и интересная. Записываю тему в блокнот. Как-нибудь подумаю, как её занимательно изложить.
Только что от вас узнал о Laravel data и сразу чекнул презентационное видео. Словил вьетнамский флэшбэк, точнее - вспомнил модели в Yii1 и Yii2. Там внутри них была, и валидация полей, и аналог ресурса из Laravel (fields()), и relations, и инструмент похожий по смыслу с Observers из Laravel (behaviors()) и т.д. и т.п. Хоть Laravel data и не является ActiveRecord и, вроде бы, никак не связан с моделью (а соответственно и БД), но такое объединение FormRequest и Resource приведёт к лишней зависимости. Но это не претензия к пакету, а скорее осознанный отказ от такого подхода. И на самом деле, очень хорошо, что появляются такие эксперименты. Мне Laravel и нравится тем, что регулярно пересматривается подход к тому или иному процессу. Вот так мы набиваем шишки и, в последствии, прогрессируем :)
Вот не очень понял сейчас. Библиотека описывает типы данных, которые можно использовать в разнообразных местах проекта с попутной валидацией. Ни с базой данных, ни с чем подобным это не связано напрямую. В том смысле, что - откуда-то пришли данные (или мы хотим отправить данные куда-то). Давайте-ка их провалидируем. И вот у нас есть для этого универсальный инструмент (а не набор из FormRequest, DTO, Resource и т.п). Или я всё-таки чего-то не понял.
Спасибо большое, Александр! 1) Про контекст не до конца понял. > У нас есть некая структура данных ctx (не содержит в себе никакого поведения). > 23:29 - Создаем createScratchFileStream - это уже явно не геттер, а метод, в который мы еще, к тому же, передаем какие-то данные > 24:42 - Структура данных должна оставаться структурой данных - никаких методов там не должно быть. Здесь как будто противоречие. 2) Ну в целом идея понятна - если у нас есть некая структура данных, и мы хотим получить какие-то данные второго или более уровня (назову это так), то мы должны делать не так $cpuManufacturerName = $cumputer->getCpu()->getManufacturer()->getName() а вот так $cpuManufacturerName = $cumputer->getCpuManufacturerName() Хорошо, допустим. А что если представить ситуация, что у нас есть интернет-магазин по продаже компьютеров и комплектующих. И у нас есть такие структуры данных: class Computer { private Cpu $cpu; private Gpu $gpu; private Motherboard $motherboard; } class Cpu { private CpuManufacturer $manufacturer; } И вот что получается - в нашем случае мы можем продавать в магазине как целиком весь компьютер, так и отдельно процессор. Но в обоих случаях нам нужно отображать о процессоре какую-то информацию - производителя процессора, например. class Computer { private Cpu $cpu; private Gpu $gpu; private Motherboard $motherboard; public function getCpuManufacturerName(): string { $this->cpu->getManufacturerName(); } } class Cpu { private CpuManufacturer $manufacturer; public function getManufacturerName(): string { $this->manufacturer->getName(); } } Естественно, структура данных в этом случае упрощена - на деле у нас CPU имеет намного больше свойст. И в итоге у нас получится, что мы должны будем написать 15 геттеров (условно) в класс Cpu, а потом еще столько же в класс Computer - это оправдано или есть какие-то другое решение в этом случае? 3) Ну со структурами данных, которые мы пишем у себя примерно все понятно. А что делать с теми, которые нам приходят из зависимостей? И в каком-то из пакетов нарушается закон Деметры. Переопределять его нет смысла. Или закон Деметры не распространяется на "пакетный код"? P.S. по поводу второго пункта сам нашел ответ - у закона Деметры действительно есть этот недостаток ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%BA%D0%BE%D0%BD_%D0%94%D0%B5%D0%BC%D0%B5%D1%82%D1%80%D1%8B#%D0%9D%D0%B5%D0%B4%D0%BE%D1%81%D1%82%D0%B0%D1%82%D0%BA%D0%B8
Как и в других правилах чистоты, здесь самое главное - гибкость кода. Создавать метод в классе, который через несколько других классов что-то там вызовет, есть смысл, если эта цепочка уже где-то повторяется. Наврядли будут задействованы все 15 геттеров. Мне кажется, что будет лучше делать сквоздные геттеры. Например нам нужно получить следующее: $payment->getOrder()->getUser()->getProfile()->getName(); Я бы в классе Payment создал метод getUserProfile() и получал данные таким образом: $payment->getUserProfile()->getName(); Завтра я могу придумать более оптимальный путь получения UserProfile из Payment и менять придётся только содержимое getUserProfile(). То есть я тут иду не до последнего метода, а до последнего класса, в котором есть необходимый мне метод. Таким образом можно снизить недостаток этого подхода (исходя из вашей ссылки). По поводу сторонних пакетов. Там нет единых законов для всех :) Я бы даже не рекомендовал как-то рефакторить сторонние пакеты, как минимум, потому что завтра может быть major update, в котором многое сменится и вам придётся заново по всему проходить. Но наследоваться и дополнять сторонние пакеты - вполне частая практика.
После этого видео, сама концепция объектов перевернулась с ног на голову. Сделал себе небольшой конспект на 4к символов, большое спасибо за полезный материал. Мартин - гений!
@@freelancer_eyes тем и правда непаханое поле.. не пойму, почему эти горе-блогеры зациклились всё на курсах.. ваши ролики, как бальзам на душу.. приятно слушать рассуждения на интересные темы и такую связную речь)
Интересная тема спасибо. Класс!! Про laravel-data я тоже не давно узнал конечно было бы хорошо если сделать отдельный ролик про него.
Про laravel-data готовлю. На следующей неделе надеюсь сделать видео.
Вот такие подстрочники по книжке очень интересны. Сколько было битв на моей практике с использованием DTO... Когда проект с глубокими корнями, где бизнес-логика крепко сидит в методах модели, уже до лампочки эстетика, принципы, культура итп. Спасибо за выпуск, ликбез полезный.
Отличный контент.
Хотел бы увидеть что-то про DDD, думаю для многих было бы интересно и полезно.
Спасибо за ваш труд!
Спасибо вам за поддержку. DDD напрашивается, да. Я сам очень люблю эту тему и она очень важная и интересная. Как-нибудь доберёмся и до неё.
Классно объясняете, можете как нибудь объяснить весь процесс работы с service container, DI, IoC, service locator, service provider ? Спасибо
Dependency Injection - тема одновременно и простая, и сложная. Важная и интересная. Записываю тему в блокнот. Как-нибудь подумаю, как её занимательно изложить.
это магия магических методов) А магия предмет темный и исследованию не подлежит :D
Спасибо большое! Больше видео хороших и разных!
Спасибо за поддержку. Присоединяюсь к пожеланию! Эх, кабы больше времени в сутках. Но это на Юпитер надо перемещаться :)
Только что от вас узнал о Laravel data и сразу чекнул презентационное видео. Словил вьетнамский флэшбэк, точнее - вспомнил модели в Yii1 и Yii2. Там внутри них была, и валидация полей, и аналог ресурса из Laravel (fields()), и relations, и инструмент похожий по смыслу с Observers из Laravel (behaviors()) и т.д. и т.п.
Хоть Laravel data и не является ActiveRecord и, вроде бы, никак не связан с моделью (а соответственно и БД), но такое объединение FormRequest и Resource приведёт к лишней зависимости. Но это не претензия к пакету, а скорее осознанный отказ от такого подхода.
И на самом деле, очень хорошо, что появляются такие эксперименты. Мне Laravel и нравится тем, что регулярно пересматривается подход к тому или иному процессу. Вот так мы набиваем шишки и, в последствии, прогрессируем :)
Вот не очень понял сейчас. Библиотека описывает типы данных, которые можно использовать в разнообразных местах проекта с попутной валидацией. Ни с базой данных, ни с чем подобным это не связано напрямую. В том смысле, что - откуда-то пришли данные (или мы хотим отправить данные куда-то). Давайте-ка их провалидируем. И вот у нас есть для этого универсальный инструмент (а не набор из FormRequest, DTO, Resource и т.п).
Или я всё-таки чего-то не понял.
👏 Просто похлопаю
Спасибо!
Спасибо большое, Александр!
1) Про контекст не до конца понял.
> У нас есть некая структура данных ctx (не содержит в себе никакого поведения).
> 23:29 - Создаем createScratchFileStream - это уже явно не геттер, а метод, в который мы еще, к тому же, передаем какие-то данные
> 24:42 - Структура данных должна оставаться структурой данных - никаких методов там не должно быть.
Здесь как будто противоречие.
2) Ну в целом идея понятна - если у нас есть некая структура данных, и мы хотим получить какие-то данные второго или более уровня (назову это так), то мы должны делать не так
$cpuManufacturerName = $cumputer->getCpu()->getManufacturer()->getName()
а вот так
$cpuManufacturerName = $cumputer->getCpuManufacturerName()
Хорошо, допустим.
А что если представить ситуация, что у нас есть интернет-магазин по продаже компьютеров и комплектующих.
И у нас есть такие структуры данных:
class Computer {
private Cpu $cpu;
private Gpu $gpu;
private Motherboard $motherboard;
}
class Cpu {
private CpuManufacturer $manufacturer;
}
И вот что получается - в нашем случае мы можем продавать в магазине как целиком весь компьютер, так и отдельно процессор.
Но в обоих случаях нам нужно отображать о процессоре какую-то информацию - производителя процессора, например.
class Computer {
private Cpu $cpu;
private Gpu $gpu;
private Motherboard $motherboard;
public function getCpuManufacturerName(): string
{
$this->cpu->getManufacturerName();
}
}
class Cpu {
private CpuManufacturer $manufacturer;
public function getManufacturerName(): string
{
$this->manufacturer->getName();
}
}
Естественно, структура данных в этом случае упрощена - на деле у нас CPU имеет намного больше свойст. И в итоге у нас получится, что мы должны будем написать 15 геттеров (условно) в класс Cpu, а потом еще столько же в класс Computer - это оправдано или есть какие-то другое решение в этом случае?
3) Ну со структурами данных, которые мы пишем у себя примерно все понятно. А что делать с теми, которые нам приходят из зависимостей? И в каком-то из пакетов нарушается закон Деметры.
Переопределять его нет смысла. Или закон Деметры не распространяется на "пакетный код"?
P.S. по поводу второго пункта сам нашел ответ - у закона Деметры действительно есть этот недостаток ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%BA%D0%BE%D0%BD_%D0%94%D0%B5%D0%BC%D0%B5%D1%82%D1%80%D1%8B#%D0%9D%D0%B5%D0%B4%D0%BE%D1%81%D1%82%D0%B0%D1%82%D0%BA%D0%B8
Как и в других правилах чистоты, здесь самое главное - гибкость кода. Создавать метод в классе, который через несколько других классов что-то там вызовет, есть смысл, если эта цепочка уже где-то повторяется. Наврядли будут задействованы все 15 геттеров. Мне кажется, что будет лучше делать сквоздные геттеры.
Например нам нужно получить следующее:
$payment->getOrder()->getUser()->getProfile()->getName();
Я бы в классе Payment создал метод getUserProfile() и получал данные таким образом: $payment->getUserProfile()->getName();
Завтра я могу придумать более оптимальный путь получения UserProfile из Payment и менять придётся только содержимое getUserProfile().
То есть я тут иду не до последнего метода, а до последнего класса, в котором есть необходимый мне метод. Таким образом можно снизить недостаток этого подхода (исходя из вашей ссылки).
По поводу сторонних пакетов. Там нет единых законов для всех :)
Я бы даже не рекомендовал как-то рефакторить сторонние пакеты, как минимум, потому что завтра может быть major update, в котором многое сменится и вам придётся заново по всему проходить. Но наследоваться и дополнять сторонние пакеты - вполне частая практика.
После этого видео, сама концепция объектов перевернулась с ног на голову. Сделал себе небольшой конспект на 4к символов, большое спасибо за полезный материал. Мартин - гений!
Вам спасибо за внимание и поддержку! Рад быть полезным. А Мартин - да, красавчик. И не он один, так что тем для разговора ещё множество.
@@freelancer_eyes тем и правда непаханое поле.. не пойму, почему эти горе-блогеры зациклились всё на курсах.. ваши ролики, как бальзам на душу.. приятно слушать рассуждения на интересные темы и такую связную речь)
Laravel-data +
Готовлю. На следующей неделе надеюсь сделать видео.
Laravel-data + ))
Готовлю. На следующей неделе надеюсь сделать видео.
в php есть функция pi() которая возвращает число пи