DTO - Data Transfer Object паттерн в JavaScript / PHP / C#

แชร์
ฝัง
  • เผยแพร่เมื่อ 2 ธ.ค. 2024

ความคิดเห็น • 41

  • @RageBerry_
    @RageBerry_ 3 ปีที่แล้ว +1

    Подписывался ради ангуляра, походу теперь ещё и ради C# буду смотреть, круто)

    • @grommaks
      @grommaks  3 ปีที่แล้ว

      С# я не планирую вводить на канал ближайшим временем)
      Но примеры из соседних языков программирования в плейлист паттернов могут попадать чисто для наглядности :)

  • @bender01
    @bender01 2 ปีที่แล้ว

    Автор, поясни плз. ссылка на гист ведет на пару файликов где один console.log и всё. а типа проект из видео есть?

  • @nexgenua
    @nexgenua 3 ปีที่แล้ว +3

    DTO - это разве не для обмена данными между сервисами или бэк фронт? Локальный DTO это скорее антипаттерн т.к. возникнет необходимость маппить данные, что локально вообще не к чему. На Nest-е DTO-шки вообще сила, документация OpenAPI(swagger) и валидация через Entity в 2 клика настраивается.
    п.с. на 9:35 вместо тернарника можно написать this.loop = props.loop ?? true; :)

    • @grommaks
      @grommaks  3 ปีที่แล้ว +2

      Тернарник не подошёл бы, так как нужно было привести к типу
      DTO обмен данными между слоями (сервисами), все верно, бэкэнд фронтенд это частный случай.
      В Nest JS вокруг DTO ещё куча настроек, также в C# через атрибуты много чего настраивается. Но документация достигается декораторами, а не самим DTO, DTO там не сложнее чем я его описал)
      Класс с набором свойств и типизацией на тайпскрипт, если бы за сваггер и валидацию отвечало ДТО, то невозможно было бы добавлять новый функционал, а так это наслоение конфигурации которая не конфликтует друг с другом и можно ещё десяток возможностей додумать под цели проекта)

  • @ОлегПетров-п4у
    @ОлегПетров-п4у 3 ปีที่แล้ว +2

    Спасибо! (Data Transfer Object)

  • @taras7844
    @taras7844 3 ปีที่แล้ว +2

    У меня на проекте бек онли джаваскрип. По архитектуре: контролеры, юзкейсы и репозиторий. Вот так типизируем в DTO поля "email = type
    .string().min(3).required() .email();" + на выход тоже есть реалтайм проверка - "const mapUsers = usersFromUseCase.map((user) => new userDTO(user))". И как то без ТС норм. линтер настроен ts проверку можно сделать глобальной + задавать значения по умолчанию.

    • @grommaks
      @grommaks  3 ปีที่แล้ว

      Тут еще декларация правил валидации идет как я понимаю
      DTO - не всегда речь о контроллере и получении данных из реквеста
      Я бы сказал что в Вашем случае DTO это результат работы маппера и валидатора
      В тайпскрипт это достигается за счет декораторов (та же логика)
      @Required()
      @Min(3)
      @Email()
      @Type('string')
      email
      Ну или в другой лакончиной форме
      Из описанного не понятно в какой момент применяется цепочка настроек, хотелось бы больше контекста

  • @Kulibins1
    @Kulibins1 3 ปีที่แล้ว +3

    Материалы все лучше и лучшее 👍 По поводу значение по умолчанию в TS, да ещё и в интерфейсе, такого сделать нельзя. Как выход из ситуации - это сделать потом Object.assign в объект, у которого уже будут значения по умолчанию. На этом строится много разных полезных техник. А вот в C# это делается легко.

    • @grommaks
      @grommaks  3 ปีที่แล้ว +1

      Спасибо коллега 😎

    • @grommaks
      @grommaks  3 ปีที่แล้ว +1

      В TS нужно было описать класс для моего случая, и использовать его как интерфейс. TypeScript позволяет такие манипуляции использовать литерал объекта и выдавать его как будто это некоторый инстанс класса.
      P.S. мой кейс - абстрактный класс
      Допустил классическую ошибку непонимания Interface vs Abstract Class (собес бы не прошел )😆

  • @levapveeskela4327
    @levapveeskela4327 3 ปีที่แล้ว +4

    материал актуальный, но много ляпов, к примеру с заданием дефотных значений в интерфесе или в 9 примере у тебя много ошибок, в C# нету типа Number и типа Bool, ты видимо попутал с TS, и ты забыл про прелести полиморфизма, мы можем принимать число или строку в высоте и длине, если сделаем параметризированный дженерик или как вариант перегрузить конструктор, либо задать тип object на эти свойства, но это плохая практика, так как будет происходить постоянный Boxing/Unboxing при типе int, либо вообще вариант с базовой моделью и двумя дочерними с разными типами, вариантов много
    public class CarouselDTO
    {
    public T Width { get;set; }
    public T Height { get;set; }
    public int ViewItems { get; set; } = 2;
    public Boolean Loop { get; set; } = true;
    }
    создаавать ДТОшки соответсввенно
    var firstCarousel = new CarouselDTO { Width = "100px", Height = "100px" };
    var secondCarousel = new CarouselDTO { Width = 100, Height = 100 };
    а похорошему у тебя должен быть маппер который будет выполнять грязную работу по мапингу DBModel или любой другой(другого слоя) в DTO и обратно, так называемый реверс
    Ну и немного обидно за слова по поводу C#, он более низкоуровневый язык, плюс со статической типизацией, поэтому парог вхождения в него выше, чем во многие динамические языки типа JS, питона, PHP, Ruby и т.п., если тебе это не нравится, это не делает его хуже этих языков.

    • @grommaks
      @grommaks  3 ปีที่แล้ว

      Спасибо за замечания
      Нужно было мне проверить код в Visual Studio, а не в VS Code...ибо небыло подсветки и поспешил с классом
      Object === any, вариант не очень
      Вложенный объект тоже вариант не упрощающий жизнь
      Дженерик вариант хороший, но это только 2 свойства...и уже 4ре комбинации на простейших int / string
      C Bool постоянно путаю, в php bool/boolean это алиасы, а по C# пока пишу не так много
      C Number тут вообще мне прощения нет) Но не в этом суть примера был
      Вернемся к дженерикам, что делать если у меня коллекция DTO и там неоднородные данные, то придется прибегнуть к object...
      И тут опять получаем boxing / unboxing
      Я не говорю что C# плохой язык) я на него перешел после 5 лет работы в php. И я говорил что в php дела похуже.
      Я просто утверждаю, что TypeScript решает задачу типизации идеально для веба. C# очень мощный язык программирования, через чур мощный для веба.
      5 лет работы с PHP и несколько лет работы с JavaScript дают свой субъективный вклад при изучении C#

    • @levapveeskela4327
      @levapveeskela4327 3 ปีที่แล้ว +1

      @@grommaks что ты имеешь ввиду под коллекцией DTO? просто коллекция в C# - это List(список), тебе никто не мешает создать параметризированную коллекцию
      var listExample = new List();
      суть C# как раз в том, что ты должен работать с неразнородными данными, а задание типа помогает выделять заранее строго определенное кол-во памяти для твоих сущностей в момент когда к ним обращаются, отсюда и эффективная работа с ней, в отличие от языков с динамической типизацией, если у тебя возможно несколько типов в одной переменной, то значит ты где-то свернул не туда, ведь суть в том чтобы получить что-то из БД(у одной сущности один тип данных) на уровне дата аксес, повзаимодействовать на уровне бизнес логики и отдать на вьюху, и DTOшка твоя используется только в промежутке для каких-либо расчётов или преобразований, и вьюмодель не равна DTO, даже если у тебя все свойства совпадают, ты всё равно должен сматить на вью модель пускай и стакими же свойствами, я просто не понимаю в чём суть вопроса, ты видимо просто заморочился на том, что писал всё время на языках с динамической типизацией и писал скорее всего 90% на фронте, поэтому не привык к строгости, зачем с бэка отдавать два возможных варианта типов?) ведь это даже архитектурно неправильно, всегда отдавай число, а на фронте уже преобразуй и мапь во что и как хочешь) либо создай разные ендпоинты котоыре будут отдавать разные модели, в одних случаях число, в другом строку, в C# можно работать с разнородными данными, но тогда его суть, как строго типизированного языка пропадает

    • @grommaks
      @grommaks  3 ปีที่แล้ว

      @@levapveeskela4327 подходы отличаются, согласен) пример в видео был не удачен с точки зрения манипуляции с данными, я бы манипулировал лишь строками

    • @levapveeskela4327
      @levapveeskela4327 3 ปีที่แล้ว +1

      @@grommaks для инта выделяется 4 байта, а для стринги в зависимости от ее длины, т.к. стринга это массив чаров то с точки зрения памяти лучше использовать инт, так как, к примеру, 100 или 100500 - 4 байта, а для “100px” - 10 байта и в базе надо хранить в типах, которые меньше весят, и трафика, чем меньше гоняешь, тем лучше, все просто.

  • @i.am.rossalex
    @i.am.rossalex 3 ปีที่แล้ว +1

    В PHP, почему не использовать __set вместо огромного набора setter'ов?

    • @grommaks
      @grommaks  3 ปีที่แล้ว +1

      Именно так делают большинство фреймворков старого образца
      Но есть ряд минусов
      1) нет подсветки (Laravel style)
      2) над сеттерами часто используют аннотации или в PHP 8 аттрибуты для дополнения логикой (например валидация или связь с колонками в БД) но это уже не DTO (Simfony style)
      3) нет возможности разбирать с помощью рефлексии (Magento style)
      Но чем хорош PHP по сравнению с C# или JS, то что можно автоматически генерировать DTO (из конфига, yaml например) в специальную папочку и автолоадер будет генерировать класс заново, если удалить старый класс.
      По принципу генерации работает Magento, чем безумно ускоряет разработку в Java стиле в PHP

    • @i.am.rossalex
      @i.am.rossalex 3 ปีที่แล้ว +1

      @@grommaks, прости, не сторонник фреймворков.

    • @grommaks
      @grommaks  3 ปีที่แล้ว +1

      @@i.am.rossalex описанные проблемы могут быть актуальны и не во фреймворке. Любой паттерн работает в связке с остальной архитектурой, а значит мы можем использовать магический метод сет для облегчения установки данных, но пожертвуем другой частью приложения. И не понятно чем это будет отличаться от ассоциативного массива :)

    • @i.am.rossalex
      @i.am.rossalex 3 ปีที่แล้ว +1

      @@grommaks согласен

  • @diatm1506
    @diatm1506 3 ปีที่แล้ว +2

    Отличный контент!

  • @MoDKona
    @MoDKona 3 ปีที่แล้ว +4

    7:57 слова про ДЕФОЛТНОЕ ЗНАЧЕНИЕ в ФИЛДЕ ИНТЕРФЕЙСА, заставляют усомниться в профессионализме автора канала.

    • @grommaks
      @grommaks  3 ปีที่แล้ว +1

      Хорошее замечание, нужно было class использовать для моего примера
      Чуток поторопился, надеюсь это мне принесет много комментов под видео и возможно дизлайков :) Спасибо за внимательность

    • @berdmival
      @berdmival 3 ปีที่แล้ว +7

      Глядя на предыдущие видео на этом канале у меня нет сомнений, что автор - трушный профессионал. А ошибиться может каждый. Плох не тот разраб, который ошибается, а тот, который не признаёт ошибку и не делает выводов. Макс же наоборот - и признал и сделал выводы и исправился, хоть и в комментах уже. Так что от меня, Максим, - респект и уважуха

  • @diatm1506
    @diatm1506 3 ปีที่แล้ว +1

    Есть впечатление что DTO появилось из за рефакторинга если в функции или методе более 2 параметров и если они логически связаны например user то их можно вынести в interface и использовать вместо 3 и более параметров

    • @grommaks
      @grommaks  3 ปีที่แล้ว +1

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

  • @ANTONTOTSKY
    @ANTONTOTSKY 2 ปีที่แล้ว +2

    В PHP обязательные поля через конструктор передать можно было

    • @grommaks
      @grommaks  2 ปีที่แล้ว

      DTO это не ValueObject, с конструктором есть свои нюансы. Но если подход с конструктором вписывается в архитектуру фреймворка или системы, то почему нет) но с трудом представляю Х полей в конструкторе, и при любом запросе добавить новые поля будут добавляться в конец списка параметров

  • @andrewdemidyuk975
    @andrewdemidyuk975 3 ปีที่แล้ว +3

    После 6го примера уже потерялся что там происходит ) typescript лучший, ну и C#

  • @alexzhaliazouski5924
    @alexzhaliazouski5924 2 ปีที่แล้ว +2

    у тебя в php в dto нет типизации? ты хоть в курсе что она появилась хрен когда, лет 5 назад?

    • @grommaks
      @grommaks  2 ปีที่แล้ว

      А напомните как описать массив строк, в какой версии появилась такая возможность? Год назад это делалось через php docs

    • @alexzhaliazouski5924
      @alexzhaliazouski5924 2 ปีที่แล้ว +1

      ​@@grommaks через коллекции. Речь правда не о том, а про дто, где вообще нет массивов

    • @grommaks
      @grommaks  2 ปีที่แล้ว

      @@alexzhaliazouski5924 DTO это объект в котором что-то хранится, это что-то может быть массивом объектов или массивом примитивов. Или как сказано выше, коллекцией. Но как указать коллекцией чего? Generic ещё не завезли в PHP. В php типизация ещё не полноценная, чтобы покрыть все потребности этого паттерна, но есть обходной путь через аннотации и рефлексию комментариев над свойствами или в более новой версии это атрибуты

  • @johnsnow7739
    @johnsnow7739 3 ปีที่แล้ว +1

    Добрый день! Пример не совсем корректный, как по мне. Больше все таки относится к фронтенду. Также не совсем понял, почему у с# "похуже" типизация?) Да и зачем вообще типизировать и строкой и числом? Бред полный, пришедший из фронденда как раз, имхо) Даже если и есть такая необходимость, то что делать потом с этой dto, если ее параметр, который может быть и числом и строкой, должен передаваться в какую нибудь другую функцию, которая принимает например только число? Будем городить проверки и приведения. Такое себе, имхо. А таких функций может быть много. Поэтому не лучше типизировать строго одним и при инициализации dto один раз привести к чему-то одному?

    • @grommaks
      @grommaks  3 ปีที่แล้ว

      Такая жизнь) приходится городить что-то потом по необходимости.
      Гибкость динамического языка программирования с типизацией раскрыты в TypeScript который не ограничен способом хранения данных, а лишь предоставляет механизм декларирования типов.
      TypeScript мощнее чем возможности типизации в C#, потому что в C# это прежде всего задача хранения свойств и оптимизации используемой памяти...а в TypeScript это облечение написания логики проекта
      Как дела обстоят с Enum со строковыми значениями в C#? Насколько мне известно, то сложно

  • @radikovichkz2470
    @radikovichkz2470 2 ปีที่แล้ว +2

    НА props.loop === false ? false : true; ЗАКРЫЛ ВИДЕО!

  • @Тёмыч-ъ6и
    @Тёмыч-ъ6и ปีที่แล้ว

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

  • @Niachan666
    @Niachan666 2 ปีที่แล้ว +1

    +

  • @resolution07
    @resolution07 ปีที่แล้ว

    Не самая лучшая реализация DTO у вас в PHP...