Грамотное ООП: организация надёжной бизнес-логики / Дмитрий Елисеев (ElisDN)

Поделиться
HTML-код
  • Опубликовано: 16 июл 2020
  • Приглашаем на конференцию Saint HighLoad++ 2024, которая пройдет 24 и 25 июня в Санкт-Петербурге!
    Программа, подробности и билеты по ссылке: vk.cc/cuyIqx
    --------
    --------
    Презентация и тезисы:
    phprussia.ru/2019/abstracts/5114
    Все мы читали про объектно-ориентированное программирование и проектирование абстрактных типов данных, но мало кто из нас использует их по назначению. И бизнес-логику проектировать и тестировать получается не у всех. Почему-то вместо красивого кода образуется переплетение вызовов, и загромождаются контроллеры.
    Вместе мы научимся раскладывать весь этот код по местам. Потренируемся в объектно-ориентированной декомпозиции для грамотного проектирования сущностей по обязанностям. Научимся сочинять ко всему этому быстрые, удобные и надёжные юнит-тесты.
    Как производить отделение UI от бизнес-логики, чтобы не было протечек слоёв в MVC. Научимся создавать агрегаты для сущностей предметной области для соблюдения инварианта. Какие проверки поместить в сущность, а какие - в сервисный слой. Как производить валидацию и использовать исключения.
    --------
    Нашли ошибку в видео? Пишите нам на support@ontico.ru

Комментарии • 63

  • @klev1983
    @klev1983 4 года назад +83

    Наверно самая короткая лекция Дмитрия =)

    • @DenysDuvanov
      @DenysDuvanov 4 года назад +1

      Ага, но качество тоже что и всегда.

    • @barrettM8
      @barrettM8 2 года назад

      Ахахаха 🤣

    • @tandev713
      @tandev713 3 месяца назад

      Если кого не устраивает, Дмитрий может вернуть деньги)))
      Пояснение: Это он так на своих занятиях говорил, когда по PHP показывал Pascal, а народ начал возмущаться))

  • @romankhalikov6759
    @romankhalikov6759 2 года назад +6

    Лучший доклад, что я видел, про архитектуру, огромное спасибо, Дмитрий!

    • @MrAmmid
      @MrAmmid Год назад

      Мне не оч нравится такая архитектура с Entity Manager. Если у меня сложный объект, у которого много полей one to many, то изменение одного простого поля повлечёт за собой сложные запросы в БД с сохранением всех остальных полей, включая запросы в другие таблицы для сохранения one to many полей.
      При чтении лота из БД нужно заполнить поле isDraft, а в его коде это поле невозможно передать в конструктор. Как тогда создать объект для лота из существующего в БД?
      Для команд с незначительными изменениями в полях лота будут скачиваться все его one to many поля, даже если они не будут использоваться.
      Короче это какой-то хайп вокруг DDD, который требует использования entity manager. Убрать Entity Manager и добавить в классы с бизнес-логикой зависимость на Repository и будет норм

    • @user-qx1jc9qv6h
      @user-qx1jc9qv6h Год назад

      Hexagonal architecture посмотри, или clean architecture

    • @user-qx1jc9qv6h
      @user-qx1jc9qv6h Год назад

      @@MrAmmid нет ни какого хайпа, это стандарты из программной инженерии. Стандарт потому что многие про это знают и многие это используют. Соответственно когда приходишь на новое место работы, и если прошлый разработчик писал код по этим стандартам, то понять и сопровождать, такой код будет намного легче. А вот если прошлый разработчик писал код исходя из своих субъективных предпочтений, типа "нравится/не нравится", то вероятнее всего, такой код будет трудно понять новому разработчику, и соответственно сопровождать, так как он не знает субъективных предпочтений прошлого автора.

    • @btcair4664
      @btcair4664 Год назад

      @@user-qx1jc9qv6h а где вы в докладе "стандарт" увидели ?

    • @btcair4664
      @btcair4664 Год назад

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

  • @Techpowers
    @Techpowers 4 года назад +2

    Наконец то доклад, в котором есть код. Практичный доклад

  • @nikolayrogoza4240
    @nikolayrogoza4240 3 года назад +7

    такая короткая лекция, что я думал тизер

  • @Techpowers
    @Techpowers 4 года назад +6

    Жаль что раздел с вопросами вырезали из видео

  • @ligat-rome
    @ligat-rome 2 месяца назад

    Грамотное ООП: организация надёжной бизнес-логики / Дмитрий Елисеев (ElisDN)
    00:00 Введение
    • Дмитрий Елисеев рассказывает о своем опыте программирования и о том, как он изучает лучшие практики и пытается привить их другим людям.
    • Он также объясняет, что такое объектно-ориентированное программирование (ООП) и как оно отличается от классово-ориентированного программирования.
    02:37 Контроллеры и фреймворки
    • Дмитрий обсуждает, как контроллеры и фреймворки используются для разделения кода и его удобного распределения.
    • Он также объясняет, как контроллеры могут быть использованы для обработки запросов и команд, а также для создания и сохранения пользователей.
    06:22 Примеры кода
    • Дмитрий приводит примеры кода, который может быть использован для создания контроллеров и обработки различных ситуаций.
    • Он также обсуждает, как можно использовать контроллеры для обработки ошибок валидации и отправки писем с подтверждением регистрации.
    09:09 Консольный режим
    • Дмитрий объясняет, что консольный режим может быть использован для выполнения административных задач, таких как активация пользователей или выполнение других действий.
    • Он также подчеркивает, что консольный режим использует другие стандартные переменные и файл, который отличается от файла, используемого в приложении.
    10:09 Создание консольных команд
    • В видео обсуждается создание консольных команд в Symfony, которые могут быть использованы для выполнения различных задач.
    • В примере создается команда для регистрации пользователя, которая принимает импут и опыт и запускает код для выполнения задачи.
    11:09 Использование очередей и микросервисов
    • Помимо консольных команд, в Symfony также можно использовать очереди и микросервисы для выполнения задач.
    • В этом случае, команды или микросервисы могут быть вызваны из очереди, и их выполнение будет контролироваться специальным классом, который будет обрабатывать запросы и отправлять их на выполнение.
    12:09 Создание общего класса для обработки команд
    • Для удобства, можно создать общий класс, который будет обрабатывать все команды, и вызывать его из разных контроллеров.
    • Этот класс будет принимать зависимости, такие как репозитории, хешер пароля, токенизатор и отправитель, и выполнять необходимые действия.
    15:09 Обработка ошибок и логирование
    • В случае возникновения ошибок, можно использовать специальный класс для обработки ошибок и логирования.
    • Это позволит упростить код и избежать дублирования кода в разных контроллерах.
    16:24 Структура кода и фреймворки
    • В видео обсуждается структура кода и фреймворки для работы с веб-приложениями.
    • Упоминается, что каждый сервер может иметь свой собственный фреймворк, что позволяет выбирать между различными вариантами.
    18:12 Взаимодействие с пользователем и контроллеры
    • В видео объясняется, что контроллеры взаимодействуют с пользователем, обрабатывают запросы, принимают и отправляют ответы, а также рендеринг.
    • Обсуждается, что контроллеры могут содержать только пи-код или консольный код, а также взаимодействие с сущностями и юзерами.
    23:12 Логика и сущности
    • В видео говорится о том, что логика из контроллеров должна быть вынесена в юс-кейсы, чтобы избежать путаницы и обеспечить разделение обязанностей.
    • Обсуждается использование инкапсуляции и принципов ООП для улучшения кода.
    25:12 Создание сущностей и использование конструкторов
    • В видео демонстрируется создание сущностей с использованием конструкторов и фабрик для создания объектов.
    • Обсуждаются преимущества использования конструкторов для создания объектов и их использования в объектно-ориентированном мире.
    27:59 Создание конструктора для лота аукциона
    • Обсуждение использования простых активных записей вместо сложных конструкторов для упрощения работы с данными.
    • Создание конструктора для лота аукциона, который принимает параметры и проверяет их на корректность.
    30:59 Тестирование конструктора лота аукциона
    • Создание тестов для проверки корректности работы конструктора лота аукциона.
    • Тестирование работы конструктора с различными параметрами и проверка на ошибки.
    34:54 Создание методов для работы с лотом аукциона
    • Создание методов для редактирования контента и цены лота аукциона.
    • Разделение методов на простые и сложные в зависимости от их функциональности.
    38:47 Создание статического метода для создания лота аукциона
    • Создание статического метода для создания лота аукциона, который упрощает процесс создания и тестирования.
    • Проверка корректности работы статического метода и его взаимодействия с другими методами.
    39:47 Создание иммутабельных методов в билдере
    • В докладе обсуждается создание иммутабельных методов в билдере, которые позволяют передавать контент без его изменения.
    • Методы проверяют, что контент является черновиком, и если это не так, то выбрасывают исключение.
    43:34 Реализация иммутабельных методов в доктрине
    • В докладе объясняется, как реализовать иммутабельные методы в доктрине, используя аннотации и типы.
    • Упоминается, что доктрина автоматически создает вложенные объекты и связи между ними.
    45:34 Создание вложенных объектов и связей
    • В докладе обсуждаются способы создания вложенных объектов и связей между ними, включая использование аннотаций и типов.
    • Упоминается, что доктрина автоматически обрабатывает вложенные объекты и связи, сохраняя их вместе.

  • @DimaTiunov
    @DimaTiunov 4 месяца назад

    2:02 а инстанс не прямая реализация объекта со свойствами, состояниями и т.д.?

  • @user-ge6pt5lp9u
    @user-ge6pt5lp9u 3 месяца назад

    Моя база

  • @spacel0rd777
    @spacel0rd777 4 года назад

    Я не совсем понимаю. Метод build LotBuilder принимает некий Member $member, который не видно чтоб использовался. И в тестах потом вызывается просто ->build().

  • @ivan_lebedev
    @ivan_lebedev 4 года назад +1

    Дмитрий, большое спасибо за доклад! Очень было интересно. Хорошо, что там у ставки три состояния, еще можно как то в методах ифами поведение разрулить. Но что будет, если это сущность "заказ" с 5-ю (условно) состояниями, с таким подходом будет сложно в каждом методе ставить ифы по состоянию + еще может состояние появиться и придется в каждом методе еще и его учитывать. Очень интересно познакомиться с Вашим виденьем по реализации "паттерна State с Doctine2" и Доменных событий. Спасибо!

    • @ElisDN
      @ElisDN 4 года назад +2

      Да, можно замутить State и сделать для него StateType.

  • @andreydmitriyev4582
    @andreydmitriyev4582 4 года назад +1

    Спасибо, Дмитрий!

  • @user-uo5nu6yu4o
    @user-uo5nu6yu4o 3 года назад +1

    Спасибо за доклад. Все как всегда на высшем уровне.

  • @VladimirSalygin
    @VladimirSalygin 3 года назад +1

    Спасибо за труд!

  • @667077
    @667077 2 года назад +2

    35:47 isDraft почему бы не сделать его тру фалс вместо двух методов isActive. Что я пропустил?

    • @koller18
      @koller18 Год назад

      на этом моменте выключил 🤝

  • @fleokan
    @fleokan 2 года назад

    15:50 а что собственно мешает вызов команды в индексе убрать в try catch и выводить нормально отренжеренную красивую 500 ?

  • @ivan_lebedev
    @ivan_lebedev 4 года назад +1

    46:30 Эванс и другие эту пачку)) называют агрегатом.

  • @mylistryx
    @mylistryx 4 года назад

    Получается, Дмитрий! Спасибо за то, что Вы делаете!

  • @ivan_lebedev
    @ivan_lebedev 4 года назад +4

    32:40 однотипные тесты даже копипастить не нужно, красивее сделать параметрические тесты

  • @andriipereverziev6287
    @andriipereverziev6287 3 года назад +2

    Крутая лекция!

  • @wcode404
    @wcode404 3 года назад +1

    47:30 Цыклические ссылки делать не обязательно. Ребята из Doctrine даже сами говорили не создавать циклические ссылки без необходимости.

  • @ivan_lebedev
    @ivan_lebedev 4 года назад +1

    14:30 Зачем флашер? Почему бы сохранение в репозитории не реализовать. типо repositoy->save($user) или update, и абстрагироваться от Doctrine

    • @locSob
      @locSob 4 года назад

      Абстракция транзакции

    • @wcode404
      @wcode404 3 года назад +1

      Или можно делать флюч по ивентам. onTerminate и т.д.

    • @ivan_lebedev
      @ivan_lebedev 3 года назад

      @@wcode404 , не знал о таком подходе.

  • @24Eugen
    @24Eugen 3 года назад +1

    Это удобно когда ты работаешь с одним объектом. А как быть если тебе нужно работать с большим объёмом лотов например. Каждый лот как объект и в нем мелкие объекты из которого состоит лот. Это увеличивает объем данных в памяти. Например если нужно обработать 50-60 тыс.

    • @tarasg7122
      @tarasg7122 3 года назад

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

    • @Tony_Sol
      @Tony_Sol 2 года назад

      lazyload для внутренних объектов и возвращать генератор из em/репозитория

  • @ivan_lebedev
    @ivan_lebedev 4 года назад +1

    48:00 Вместо сурогатного ключа + уникального индекса, я обычно делаю составной праймери ключ из lot_id и member_id

    • @ElisDN
      @ElisDN 4 года назад +2

      Связь winnerBid тогда будет сделать трудно. А так да, можно двум связям проставить @Id.

  • @yerzhan
    @yerzhan 3 года назад

    Дмитрий как всегда крут

  • @dmitry-popov
    @dmitry-popov 3 года назад +5

    Фрейморки кроме котролеров и роутинга , предоставляют еще кучу функционала , различные ORM ,хелперы, валидаторы итд. Думаю для +95% проектов неоправдано изолировать слой бизнес логики от фремворка .

    • @wcode404
      @wcode404 3 года назад +2

      Кроме того, в большинстве случаев трудозатраты не окупаются. Например ORM накладывает свои ограничения на модели (даже Doctrine) и попытка отделить модели от ORM сделает использование ORM бессмысленным, а код persistent слоя монструозным.

    • @nikitaproit
      @nikitaproit 3 года назад

      В большинстве случаев трудозатраты окупаются. Если вы посмотрите в других языках можно использовать ORM и настроить автоматический мапинг на конвенциях(которые в случае чего можно настроить), с минимальными ограничениями на модели(иногда и вовсе без ограничений). В коде нужно сказать только "дай мне агрегат класса X", и все, а в мидлваре перед завершением запроса написать что-то вроде "если что-то изменилось сохрани". Кроме этого кода, кода использующего ORM в проекте вообще не будет, разве что мапинги в трудных местах ручками написать, но таких мест парочка на проект в 1кк LOC. А вот эти все "фреймворки дают много фишек" это булщит который не нужен в 95% проектах не на уровне инфраструктуры, а пихать их всюду, так во фронтенд идите, там такой код выкидывают каждый день тоннами. А потом возникают вопросы что дешевле найти разработчика который поправит одно поле в форме на каком нибудь мертвом фреймворке и на лайвскрипте или переписать на реакт =)

  • @btcair4664
    @btcair4664 Год назад +1

    очень много туфты в докладе - наброс для джуна(не более). Вывод вообще ппц - типа спрятали изменения состояний в методах-командах ))) но состояния сами себя не меняют, поэтому в любом случае нужно будет реализовать не публичные методы для работы с состояниями. А обращение к паттерну Информационный эксперт это "грамотное ООП" ? ой блин не хочется токсичить , но ребят , берите информацию из разных источников и думайте своей головой. А за доклад спасибо - он и нужен чтобы его обсуждать, спорить и расти дальше.

  • @callpack96
    @callpack96 3 года назад +1

    по фотке сразу видно, программист

  • @leoomgs9801
    @leoomgs9801 3 года назад +2

    Первая половина - вообще банальщина

  • @azamatk4302
    @azamatk4302 3 года назад

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

    • @azamatk4302
      @azamatk4302 3 года назад +1

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

  • @pavlobezdvernyi9348
    @pavlobezdvernyi9348 4 года назад +1

    помоему Дима говорит о Laravel без уважения !

    • @vitaliyoleynik7659
      @vitaliyoleynik7659 4 года назад +3

      А с чего должно быть уважение? Когда Laravel не поощряет такого стиля написания, там связь Controller и Model и все можно вызывать где угодно

    • @c3tv3r
      @c3tv3r 3 года назад +4

      Laravel - редкостная гадость: магические методы, куча наследования, трейты без интерфесов, фасады и т.д.

    • @pavlobezdvernyi9348
      @pavlobezdvernyi9348 3 года назад

      @@c3tv3r -_-

    • @webberru
      @webberru 3 года назад

      потому он адепт божественного yii

    • @webberru
      @webberru 3 года назад +1

      @@c3tv3r "Laravel - редкостная гадость: магические методы, куча наследования, трейты без интерфесов, фасады и т.д."
      )) привет Дима!

  • @JohnDoe_777
    @JohnDoe_777 4 года назад +3

    Супер конечно нудный чел. Больше позвать некого?

    • @qAntBcn
      @qAntBcn 3 года назад

      на скорости 2 норм смотреть