Почему нельзя возвращать NULL?

Поділитися
Вставка
  • Опубліковано 20 чер 2024
  • Негативные последствия возвращения Null и как же работать правильно.
    Курс, о котором шла речь в видео: Enterprise patterns - bit.ly/3hYyWhk
    Курсы для новичков:
    JAVA - bit.ly/2Z42wL6
    JAVA Start - bit.ly/3boc7Ba
    Инструментарий JAVA - bit.ly/32Xwl0S
    Automation QA (Java) - bit.ly/3gZe8oJ
    ANDROID - bit.ly/3jWAedB
    C#/.NET - bit.ly/331EcL8
    C# START - bit.ly/3lQfLZF
    PYTHON - bit.ly/2Z4UBgo
    FRONT-END - bit.ly/2Z42NxC
    WORDPRESS Developer - bit.ly/2EWUsET
    SALESFORCE Developer - bit.ly/3lMsf4k
    UI/UX дизайн - bit.ly/32TaveV
    Project management - bit.ly/3gSAmbP
    Обучение на проекте - bit.ly/2DsgpuZ
    Продвинутые курсы для состоявшихся девелоперов:
    GRASP and GoF Design patterns - bit.ly/354aeIM
    Сайт Foxminded: bit.ly/3lNYikt
    Foxminded в ФБ: / foxmindedco
    FoxmindEd в Instagram: / foxminded.ua
    Foxminded в VK: foxminded
    Мой Telegram: t.me/nemchinskiyOnBusiness
    Мой блог: www.nemchinsky.me
    0:00 - вступление Сергея Немчинского
    00:27 - кто еще считает, что Null возвращать нельзя?
    02:02 - почему нельзя возвращать NULL: обработка ошибок вручную
    04:48 - почему нельзя возвращать NULL: неоднозначное понимание
    06:16 - реклама
    07:22 - почему нельзя возвращать NULL: нарушение мышления программиста, нагромождение кода
    10:38 - почему нельзя возвращать NULL: медленный провал, затруднение поддержки системы
    13:31 - история про индусов
    15:13 - использование Null в изменяемых и незавершенных объектах
    17:15 - как же тогда работать?

КОМЕНТАРІ • 1,1 тис.

  • @alexander_brun
    @alexander_brun 3 роки тому +820

    Всю пандемию возвращал null, теперь коллекторы названивают...

    • @LionKing-qp1lk
      @LionKing-qp1lk 3 роки тому +12

      Посмотри кузнецова, научись экзепшона всем вставлять

    • @Mirloom
      @Mirloom 3 роки тому +13

      Так можно и П.Е получить)

    • @LobanovSpace
      @LobanovSpace 3 роки тому +2

      Вахах

    • @LedoCool1
      @LedoCool1 3 роки тому +1

      @@LionKing-qp1lk нелюбители исключений уже идут за вами.

    • @CarelessPossum
      @CarelessPossum 3 роки тому +25

      garbage collector'ы

  • @IPWchild
    @IPWchild 3 роки тому +159

    Не возвращай нал, возвращай безнал!

  • @sergeimenshikov8611
    @sergeimenshikov8611 3 роки тому +96

    Когда пацики с района стреляют сигаретку, а ты, вместо ответа "не курю", падаешь и притворяешься мёртвым.
    добавлено:
    Забыл, ещё можно отдать им пустую пачку)

    • @maxlich9139
      @maxlich9139 3 роки тому

      а исключение - это что в таком случае?)

    • @daniilpalii6743
      @daniilpalii6743 3 роки тому +4

      @@maxlich9139 , падение же

    • @maxlich9139
      @maxlich9139 3 роки тому

      @@daniilpalii6743 да это вроде null

    • @sergeimenshikov8611
      @sergeimenshikov8611 3 роки тому +8

      @@maxlich9139 не, нул - это ответить "нету сижек". Исключение - упасть.

    • @RossiYek
      @RossiYek 3 роки тому +4

      Sergei Menshikov нет, исключение - это дать ему по башке и сказать: разберись в своих ошибках.

  • @user-rj4hq2vb2n
    @user-rj4hq2vb2n 3 роки тому +404

    - Микола, слыхав, як паскали наш null называють?
    - Як?
    - Nil! Поубивав би гадів!

    • @evgenasd8892
      @evgenasd8892 3 роки тому +2

      Он так и называется в паскале

    • @user-rj4hq2vb2n
      @user-rj4hq2vb2n 3 роки тому +2

      Avazart my bad😂

    • @ivanskorokhod2959
      @ivanskorokhod2959 3 роки тому +3

      Олег Литвиненко в Свифте тоже nil. Я кстате тоже целую лекцию по этому поводу записал

    • @listenheart5967
      @listenheart5967 3 роки тому +8

      на lua тоже

    • @user-yh7zc9ke4s
      @user-yh7zc9ke4s 3 роки тому +3

      да и в golang

  • @199aa
    @199aa 3 роки тому +149

    Однажды русский программист из Калифорнийской компании вернул «zhopa», вместо Null. Всем понравилось, стали использовать. Потом стали нумеровать zhopa1, zhopa2, когда просто zhopa было недостаточно. Как-то звонят из Тайваня, говорят остановился весь завод, мы не понимаем из-за чего - даёт ошибку zhopa37 !

    • @user-bf1zg6tx6u
      @user-bf1zg6tx6u 3 роки тому +27

      Ты что-то перепутал. Ошибку zhopa37 выдавал сервер Диабло3 на релизе.

    • @alsu666
      @alsu666 3 роки тому +25

      Однажды русские программисты из Германии, ночью, не зная как назвать методы, назвали их xyinja1, xyinja2. Так никто и не возражал.

  • @199aa
    @199aa 3 роки тому +219

    Теперь буду вместо Null возвращать «Sergey Nemchinskiy»

    • @drKatzman
      @drKatzman 3 роки тому +37

      NemchinskyDislikesNullException

    • @pompei2
      @pompei2 3 роки тому +17

      SergeyNemchinskiyException

    • @user-qv4hn6qq4n
      @user-qv4hn6qq4n 3 роки тому +15

      А если булево, то NotNemchinskyException

    • @sergeyg436
      @sergeyg436 3 роки тому +26

      Лучше ссылку на это видео

    • @schrodingers_kater
      @schrodingers_kater 3 роки тому +2

      😂

  • @user-vf8vd2we3b
    @user-vf8vd2we3b 3 роки тому +133

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

    • @LobanovSpace
      @LobanovSpace 3 роки тому

      Кек

    • @inglevir
      @inglevir 3 роки тому +11

      Типичный медлннный фейл :)

    • @dreyktroll4490
      @dreyktroll4490 3 роки тому +3

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

    • @Kudriako
      @Kudriako 3 роки тому +3

      Это пример, когда эксепшен проскакивает вверх по коллстеку, но каждый метод "считает", что обработать должны еще выше. А потом все приложение крешится.

  • @lego12239nn
    @lego12239nn 3 роки тому +159

    Ждём следующий выпуск - "почему нельзя возвращать -1".

    • @MikhailKolesnikov
      @MikhailKolesnikov 3 роки тому +9

      Почему любой стейт надо в енум, даже если там только он/офф

    • @TeppopucT
      @TeppopucT 3 роки тому +9

      @@MikhailKolesnikov потому что любим обмзаться ооп

    • @0imax
      @0imax 3 роки тому +7

      @@TeppopucT enum - ни разу не ооп, просто превращение цифр в читаемый вид и контроль за тем, чтобы не засунули туда то, чего там быть не может. Внутри-то там всё-равно цифры живут.

    • @0imax
      @0imax 3 роки тому +4

      @@MikhailKolesnikov Чтобы код был красивый. Енум не жрёт ресурсов, он просто даёт бОльшую свободу и контроль, чем если делать то же самое через константы.

    • @Mike19910711
      @Mike19910711 3 роки тому

      В Си, например, вообще нет эксепшонов. Там функции либо через возвращаемое значение какой-то код возвращают (типа 0 - всё норм; отличное от 0 значение - какая-то ошибка и т.д.); либо в функцию в качестве параметра передаётся указатель на int, в который функция выводит код ошибки.

  • @drovoseg
    @drovoseg 3 роки тому +23

    Допустим, у класса User есть поле с типом Group которое может быть пустое. У Group поле title и другие.
    Нам нужно вывести список юзеров с названиями их групп. Как быть без null? Возвращать вместо группы объект типа Group с пустым полем title? Это еще больше багов породит, причем намного хуже чем NPE, например в БД добавится пустая строка.
    И как по сети передать, тому же фронту? Фронт получит какой-то объект с пустым title, ему это дикое условие проверять надо будет вместо простого == null.

    • @grommaks
      @grommaks 3 роки тому +1

      Ну тут была больше речь о возврате null если не удалось посчитать или загрузить данные из метода / сервиса. Что то не получилось, выкинь исключение определенного типа. Суть видео можно было свести к тому, что в интерфейсе можно перечислить положительный результат работы метода и все возможные исключения. Null не дает понимания о природе ошибки

    • @drovoseg
      @drovoseg 3 роки тому +8

      @@grommaks В случае ошибки null возвращать нельзя, это понятно. В моем примере null это не ошибка, юзеры без групп это нормальный случай. В видео речь о том, что null никогда нельзя возвращать.

    • @grommaks
      @grommaks 3 роки тому

      @@drovoseg в этом случае null это нормально

    • @askolit1458
      @askolit1458 3 місяці тому

      @@drovoseg в чем проблема вернуть пустой масив групп? Если их нет? На фронте проверят через groups.length!==0

    • @SergeyNemchinskiy
      @SergeyNemchinskiy  Місяць тому

      использовать паттерн NullObject. Я же рассказывал :)

  • @alexeylesnov8203
    @alexeylesnov8203 3 роки тому +180

    Краткий итог всего видео: Рубисты молчать.

    • @LobanovSpace
      @LobanovSpace 3 роки тому

      :D

    • @KostiaBazrov
      @KostiaBazrov 3 роки тому

      ​@Глядач че бьля7

    • @itcloudguy
      @itcloudguy 3 роки тому

      Гоферам тоже заткнуться! :)

    • @chakchaky8521
      @chakchaky8521 3 роки тому

      А в кристале как удобно с Nil работать... Видео дичька беспонтовая. Если обизяна сидит и не ждёт nil от выборки - ну кто тут её доктор?
      фу короче. Старая дичь.

    • @alexanderskusnov5119
      @alexanderskusnov5119 2 роки тому

      Не знаю про Ruby, но если это функциональное программирование, то в Haskell это норма: поиск в словаре - результат Maybe, т.е. или Nothing (ничего не найдено), или значение в обёртке Just.

  • @BukasovMaxim
    @BukasovMaxim 3 роки тому +39

    1) Тема Optional не раскрыта :)
    2) Еще можно было бы акцентировать внимание на том, что если есть метод, который может найти и вернуть *несколько* объектов, а может и ни одного (0..*), то в случае если не нашёл ничего, то обязательно нужно возвращать пустую коллекцию (или пустой массив), а не тупо null "для экономии памяти". А то видел я такое как-то. В результате вместо обычного итератора, который для 0 объектов просто сработал бы 0 раз, приходилось писать if+итератор.
    P.S. 8:55 "... если каждый метод на входе будет проверять не null ли все его 20 параметров..." - явная проверка параметров *публичных* методов на null (а точнее не конкретно на null, а вообще на корректность) является хорошим тоном при разработке API: у публичного метода должна быть предусмотрена "защита от дурака".

    • @linkernick5379
      @linkernick5379 3 роки тому +3

      Да, тоже ждал, когда будет речь об Optional и - о, боже, нет! - о монадах, но видимо Сергей слишком Star.

    • @TwilightSun32
      @TwilightSun32 3 роки тому +4

      так чего далеко ходить, в жабаскрипте так штатный match от строки работает. типа если ничо не нашел возвращает undefined. какая религия запрещает возвращать пустой массив - ума не приложу. в итоге условия вставлять надо (да, иногда это 4 символа лишних но некрасиво же).

    • @user-bs6qw5gr1o
      @user-bs6qw5gr1o 3 роки тому +2

      @@TwilightSun32 Тоже в первую очередь вспоминается match из JS. Он возвращает null, а не undefined. Но к нему претензии только с точки зрения неудобств. Это не значит, что никакая функция не должна возвращать null. Видел такое решение, и сам перенял: ( s.match(…) *|| [ ]* ) - то есть в любом случае возвращается массив, это заметно упрощает алгоритмы.

    • @TwilightSun32
      @TwilightSun32 3 роки тому

      @@user-bs6qw5gr1o да, я именно такую запись и имел ввиду когда писал про четыре символа. То что синтаксис позволяет сделать проверку краткой не отменяет же её наличия.

    • @user-sz1jw2wt7v
      @user-sz1jw2wt7v 3 роки тому

      Он хотел сказать Optional но у него получилось Опшены :D ну ладно, и на том спасибо)

  • @andrey.shpilevoy
    @andrey.shpilevoy 3 роки тому +20

    И весь код в try, а в catch перезапуск приложения, и вот тебе абузоустойчевость)

  • @user-bk1lh9gf8n
    @user-bk1lh9gf8n 3 роки тому +33

    Как будто мне не придётся проверять параметры на null, если в своих программах я перестану возвращать null. Есть же тысяча коллег, чьим кодом я пользуюсь.

    • @user-fg7hf4qo8m
      @user-fg7hf4qo8m 2 роки тому +2

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

    • @beltar2
      @beltar2 2 роки тому +5

      @@user-fg7hf4qo8m Отсутствие результата - это тоже результат, и религиозные фанатики могут идти лесом. Если вы засунете в функцию exception, то это не поменяет ничего, потому что вызывающий код точно так же ставится перед фактом необходимости проверки данного исключения, если оно вылетит. Т. е. все это по факту пустой треп о том, куда ставить проверку, но никак не отменяет самой проверки.

    • @user-fg7hf4qo8m
      @user-fg7hf4qo8m 2 роки тому +1

      @@beltar2 если функция возвращает null, бывает очень трудно найти причину ошибочного поведения, т.к. программа свалиться где-нибудь позже, иногда сильно позже. И там, в отладке, единственно, что вы увидите - это то, что пришёл null. Гораздо легче исправить ошибку, если программа вылетит непосредственно на ней.
      Отсутствие результата тоже имеет право на существование в некоторых сценариях, но тогда это должно быть сразу оговорено. Хорошо, если язык сам заставляет делать проверки в таких случаях.

    • @beltar2
      @beltar2 2 роки тому

      @@user-fg7hf4qo8m Тут я с вами соглашусь, что мерзкое окошко исключения сразу будет неплохо бодрить, однако данная ситуация все равно может быть автоматически распространена на любые вызовы, не нашел в коллекции что-то, вернул индекс -1. Это точно так же может пойти по системе, а может в следующей строке рвануть "List Index Out of Range" или как там оно в конкретном языке называется. В этом плане вероятность ухода ошибки дальше сильно снижается, т. к. если вы получали объект, то вы хотели с ним что-то сделать вот прям сейчас, а значит и по хоботу получите тут же. Кроме того, сама по себе ситуация, когда результата нет является первой, которую следует тестировать, если этого не делается, то тут извините, но говорить вообще не о чем.
      Но в целом обрабатывать исключения намного геморойнее, чем числовые коды (или enum), и делать это во всех случаях, когда возможно отсутствие результата, неважно в каком виде это сигнализируется, приятного мало.
      Как вариант, могу предложить что-то вроде BOOL TrySomething(int Id; out MyClass ReturnValue); Даже если язык позволяет не проверять вызов, сама по себе конструкция уже говорит: "Засунь меня в if".

    • @user-fg7hf4qo8m
      @user-fg7hf4qo8m 2 роки тому

      @@beltar2 исключение обрабатывать проще: достаточно обернуть в try самый верхний вызов. Но я говорил не об этом, а о статическом анализе.
      Например, если функция может вернуть null, компилятор должен заставит отработать такую ситуацию. В таком случае, у вас гарантировано не будет ошибок null reference. Например, такая фишка есть у typescript.

  • @clauseclause6640
    @clauseclause6640 3 роки тому +29

    Правильно было бы: "Возвращать null в ДЖАВЕ, если ты еще учишься и не совсем понимаешь последствия этого - не стоит, но в конкретных ситуация опытные программисты вполне могут его использовать, а в других языках это вообще может быть хорошей практикой".

    • @Lee-su5pg
      @Lee-su5pg 3 роки тому +3

      Опытные программисты-говнокодеры могут его использовать и на практике используют постоянно. А те, кто знает, что это тупо всегда находят способ его не использовать. Создатель Null сказал, что это была самая крупная ошибка в его жизни, которая нанесла за последние 60 лет убытков многим компаниям на миллиарды долларов и продолжает наносить, так как NullReferenceException кидается в 50% случаев неполадок в программе.

    • @wcode404
      @wcode404 3 роки тому +2

      @@Lee-su5pg я не джавист и мне вот интересно, это такая особенность языка, что NullReferenceException аж в 50% случаев? В моей практике это крайне малый процент.

    • @clauseclause6640
      @clauseclause6640 3 роки тому +6

      Александр Lee ну мужик, если я начну приводить примеры где null НЕОБХОДИМО использовать, тыж начнешь объяснять, что автор это уже сказал и это все понятно, а ты про говнокодеров... Конструкция null необходима, а говнокодеры и без нее найдут способы наговнокодить. А вот то что в джаве это такая проблема, когда во многих яп возвращения null является нормальной практикой, это уже претензии к джаве.

    • @IvanGaydamakin
      @IvanGaydamakin Рік тому

      звучит как типичное название аниме

    • @arboleet
      @arboleet Рік тому

      на си так вообще единственной

  • @alexsokol1086
    @alexsokol1086 3 роки тому +14

    надеюсь следующее видео будет о том, почему нужно юзать котлин с null-safe и возвращать нулл

  • @user-hs8rz9lv1v
    @user-hs8rz9lv1v 3 роки тому +21

    Что за бред? Почему null приравнивается к Exception или вообще к какой-то ошибке? Null это нормальное значение, которое показывает, например, что в мапе нет значения по этому ключу.

  • @now.7348
    @now.7348 3 роки тому +26

    "возврат НАЛА =откат=преступная коррупция" :))

  • @Nandarion
    @Nandarion 3 роки тому +4

    Отличное объяснение, но хочу добавить, что в современных языках существует концепция nullable типов.
    В rust например, в стандартной библиотеке для возврата нулевого указателя есть специальный тип Option, который может содержать в себе или объект или None. Если функция возвращает этот тип, то программист перед использованием объекта должен его явно "сконвертировать", либо проверив на None при помощи if let, либо вызвав у него специальный метод, кидающий исключение в случае None. Очень удобно, и никто не сможет "забыть" проверку на null, как часто бывает в Java или "забыть" try{} catch{}, как часто бывает в с++.

    • @user-jd4rl7im6d
      @user-jd4rl7im6d Рік тому

      Так в Java тоже есть Optional. Но это ведь не null.

  • @ni55an
    @ni55an 3 роки тому +101

    Ну вы даете, народ! Из-за какого-то NULL заставили человека писать видео на 20 минут

    • @pompei2
      @pompei2 3 роки тому +3

      Да это ещё что - какой-то там NULL заставил создателя Java рвать на себе волосы.

    • @LobanovSpace
      @LobanovSpace 3 роки тому

      Хехех

    • @0imax
      @0imax 3 роки тому

      А мы-то что? Он первый начал!

    • @alexlitsov9032
      @alexlitsov9032 3 роки тому

      Он только рад

    • @kirillperov3843
      @kirillperov3843 2 роки тому

      @@alexlitsov9032 Сергей Немчинский любит поболтать.

  • @magadash9341
    @magadash9341 2 роки тому

    Мордочка))))) Так мило))))
    А вообще супер объяснения, огромное спасибо за работу!

  • @user-re8zf8jr3e
    @user-re8zf8jr3e 3 роки тому +121

    Вы посмотрите на API Java. Там огромное кол-во методов, которые выкидывают NULL, но это не особо волнует всех этих экспертов.

    • @protiv_bio
      @protiv_bio 3 роки тому +44

      А кто сказал, что api java написано гениально? Смотришь в исходники, а там код как будто обфусцирован. Ну и совместимость, тянущуюся 25 лет, никто не отменял.

    • @user-re8zf8jr3e
      @user-re8zf8jr3e 3 роки тому +16

      @@protiv_bio если вы говорите о том что API Java написано ужасно и на нем не следует учиться, тогда можно считать разработчиков самой Java - больными людьми. Просто гениальный подход, пишем код на Java, но исходники стандартных либ не смотрим, т.к. там все сделано через одно место.

    • @superspy2008
      @superspy2008 3 роки тому +14

      @@protiv_bio на самом деле, если глянуть в код .NET - там тоже как будто обфускация. Но читая-читая-читая Рихтера или других толковых людей, начинаешь понимать, что это на самом деле очень сложная оптимизация. А где оптимизировать, если не в фреймворке

    • @Igor-hz2gp
      @Igor-hz2gp 3 роки тому +2

      тоже самое в Android SDK

    • @woodzimierz9621
      @woodzimierz9621 3 роки тому +8

      За годы существования Java к самому ООП неоднократно менялись подходы, но обратная совместимость, как уже упоминали, ни кто не отменял.

  • @user-ps1lu9gp5f
    @user-ps1lu9gp5f 3 роки тому +13

    Долго слушал, и всё что я понял, так это то что автор сразу предлагает писать больше кода только ради того, чтобы не было NULL.

  • @Dimontius1
    @Dimontius1 3 роки тому +1

    Классный формат видосов!

  • @toha152
    @toha152 3 роки тому

    Спасибо большое, было полезно данную информацию услышать!!)))

  • @IuriiVishnevskyi
    @IuriiVishnevskyi 3 роки тому +22

    Осталось теперь запилить видео почему нельзя кидаться эксепшнами. И где взять тип Either. И зачем NULL object, если есть Optional.

    • @errandir
      @errandir Рік тому

      Optional закрывает конкретный случай, а null-объектов может быть несколько, если бизнесово их нужно различать.

  • @baratorch
    @baratorch 3 роки тому +17

    c++: постоянно использую возвращение nullptr в методах/функциях типа FindSomething(). Очень удобно. И когда это Something не найдено - это один из штатных вариантов, не требующий никаких эксэпшнов. В стандартных с++ контейнерах метод find возвращает какой-нить итератор end() в котором связанный указатель на Something равен nullptr. Какая тут принципиальная разница? Кроме того что без лишней конструкции в виде итератора - удобнее.
    NullObject - это же по смыслу то же что и NULL, нам все равно для него нужно будет писать код отличный от случая с норм объектом типа if (NullObject != FindObject()) ... ручками в клиентском коде. И если такой NullObject заполненный дефолтными значениями попадет потом в какой-то список, чем это будет лучше попадания NULL? Уж лучше пусть прога упадет при обращении к нулевому указателю, чем не упадет и будет производить какие-то (рушащие логику) операции с дефолтными значениями NullObject, считая их правильными значениями полноценного Object.

    • @madcalm2024
      @madcalm2024 2 роки тому

      NullPtr - смарт-указтель, он прямо говорит что null в нем неслучайное значение

  • @brazq
    @brazq 3 роки тому

    Лично для меня оч полезный видос оказался. Спасибо.

  • @user-nm8zk4hn4q
    @user-nm8zk4hn4q 3 роки тому

    Серега спасибо за видео!!

  • @dvdrelin
    @dvdrelin 3 роки тому +8

    Спорный вопрос. Обкладывать все вызовы try-catch? Что ожидать? Какой крутизны должен быть стек catch-a
    Или другое - ловиться в catch наверху и разруливать стектрейс?
    Что мешает использовать ?? .? подводя к дефолту/nullObject если прям очень надо?

  • @kirillkir6268
    @kirillkir6268 3 роки тому +56

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

    • @0imax
      @0imax 3 роки тому +1

      Тут уже надо конкретный случай рассматривать. Возможно, то, что в map может не оказаться объекта - это следствие неправильной архитектуры, и там вполне подошли бы nullObject-ы. Либо обращение к потенциальному источнику null-ов построить как-то иначе. Либо структура данных сделана не лучшим образом.
      Писал моды на Lua для одной игрушки - там весь код приходилось увешивать проверками, потому что, получив какой-то конкретный объект, не было никакой гарантии, что все поля у него заполнены, и при обращении к ним приходилось сначала проверять, "есть ли кто дома".
      Такой косяк был из-за архитектуры, а конкретно - нарушения LSP: в одних "объектах" все поля были заполнены нормальными данными, в других объектах, "наследованных" от того же родителя, часть полей могла просто не использоваться и быть равной nil (аналог null в lua). Будь архитектура правильной, "классы" бы расширялись, а не обрезались под конкретный случай, и лишних проверок не потребовалось бы.

    • @drovoseg
      @drovoseg 3 роки тому +6

      +1 Эксшепны для бизнес логики это тоже плохой паттерн

    • @grommaks
      @grommaks 3 роки тому +1

      @@user-lq1gk7li9y Естественно, но эксепшн имеет тип, может взлететь до первого catch, catch может отлавливать свой тип исключений, там хранится место ошибки.
      Т.е. вы пытаетесь загрузить продукт по id...зачем это делать если мы не уверены что такой id существует? Если продукт был удален в промежутках получения этого id клиентом и совершением запроса, то это исключение. Т.е. исключения не должны отрабатывать в штатном режиме...но они упрощают работу с кодом

    • @zariumsheridan3488
      @zariumsheridan3488 3 роки тому +2

      не знаю как в Жабке а в .Net если пытаешся из Dictionary вытащить что то при помощи dict[key] он кинет keyNotFound или что то в этом роде. для таких случаев есть TryGet

    • @grommaks
      @grommaks 3 роки тому

      @@zariumsheridan3488 Незнаю как в жаба, но в php есть оператор @ чтобы заглушить вылетание ошибок и нотисов, а потом делаешь иф и выкидываеш исключение...чтобы все работало однородно.
      А в шарпах получается есть два вида try и tryGet?

  • @user-ot7wm6vo8j
    @user-ot7wm6vo8j 3 роки тому

    Спасибо за рекомендации книг! 👍

  • @SatorLive
    @SatorLive 3 роки тому

    Спасибо за хорошую и полезную мысль.

  • @f00b4r123
    @f00b4r123 3 роки тому +20

    GetObjectByNameOrThrowObjectNotFoundIfNotFound

  • @vladimirsadovnikov3797
    @vladimirsadovnikov3797 3 роки тому +25

    - Почему не кинуть exception из метода?
    - Потому что генерация exception - дорогая по времени операция.
    Что лучше?
    Objecx x = callMethod();
    if (x == null) { // Мы знаем, что если метод не отработает, то вернётся null
    // handle error
    }
    try {
    Object x = callMethod();
    } catch (SomeException x) { // Мы должны знать, какой exception ловить
    // Handle error
    }
    Что, сильно ситуация поменялась? Не думаю. Всё равно ошибки надо (сюрприз!) отрабатывать, от этого никуда не деться.
    - Код полезет в коллекцию и получает NPE.
    - Не выполнена конвенция о том, что в коллекции не могут храниться NULL-объекты.
    - Метод называется getSomethingByName(), а на самом деле должен называться getSomethingByNameOrReturnNull();
    - А JAVADOC для чего существует? Что мешает в описании параметра написать "can return null if "
    - Вы получаете объект, который NULL;
    - Брехня. Вы получаете ССЫЛКУ, которая не ссылается на валидный instance объекта, а не объект. Нарушением ООП это не является от слова совсем.
    - Мы спускаемся с абстрактного мышления до уровня байтиков.
    - #&*%*! А машина чем оперирует? Абстрактным мышлением вашим или байтиками? Вы железяку программируете или какую-то абстрактную эфимерную среду?
    - Если вы упали сразу, то у программистов не возникает вопросов, как обработать этот Exception.
    - Ну, смотря как упали. Если упали на проде и повредили какие-то важные данные этим падением (например, вызвали инконсистентность). Вообще-то, падать, в принципе, нехорошо.
    - Если вы пишете серьёзную систему, весь основной блок находится в try/catch.
    - Ой не зарекайтесь. Если система подразумевает обработку ошибок при вызове каждого метода, никакой try/catch вас не спасёт. Мало того, жирный try/catch - это антипаттерн. Вы чему людей учите?
    Ну и т.д. и т.п.

    • @homo-ergaster
      @homo-ergaster 3 роки тому +3

      Вообще-то когда метод может кинуть Exception у него будет throws и компилятор прогера пошлет если он этот Exception не обработает или не перекинет. А если метод вернет null, то прогер вообще не в курсе вернул метод null или нет и может ли он вернуть null в принципе.
      "А машина чем оперирует". А компилятор на что? Не надо опускаться до процедурного программирования.

    • @vladimirsadovnikov3797
      @vladimirsadovnikov3797 3 роки тому +1

      @@homo-ergaster Если exception наследуется от RuntimeException, то его упоминание в throws (сюрприз!) необязательно. Иначе везде бы были throws NullPointerException и тому подобные описания.

    • @user-qh2ru8wk4t
      @user-qh2ru8wk4t 3 роки тому +5

      Разница между null и эксепшеном в том, что в случае с эксепшеном ты знаешь ЧТО именно обрабатывать, а в случае с null нифига не знаешь. А если этот null перед тем как положить программу пролетел через 100500 методов, ты вообще хрен БЫСТРО разберёшься, как исправить баг (конечно, если твоё приложение - не калькулятор из десяти-пятнадцати файлов). А если ты ещё и кидаешь null из МНОГИХ методов, будешь сидеть и офигевать. Что? Откуда? Какого хрена? Я же всё правильно сделал. 🙃 А если дотуда дошёл эксепшен, ты смотришь - эксепшен такой-то, ага - вот эта хрень значит отвалилась - по-быренькому исправил и не получил сильно по башке (или как вариант, не встрял на многомиллионные издержки).
      В итоге что лучше: пожертвовать чуть больше памяти, или сидеть потом офигевать? Вопрос, конечно, философский. Но у меня есть подозрение, что тому, кто любит всё делать "руками", не нужны ООП-языки. Если памяти действительно так жалко, может нужно задуматься над тем, чтобы все проги сразу писать на ассемблере? 🙃

    • @vladimirsadovnikov3797
      @vladimirsadovnikov3797 3 роки тому +3

      @@user-qh2ru8wk4t То же самое можно сказать про RuntimeException, который пролетел через 10 методов. Вы точно также нифига не поймёте, что произошло и почему, потому что исходные данные, которые привели к ошибке, в описании к RuntimeException не сохранены.
      Вообще, если у вас возникают проблемы с пробросом NULL на 10 уровней вверх, то у вас, скорее всего, проблема с архитектурой вашего приложения.
      > по-быренькому исправил и не получил сильно по башке (или как вариант, не встрял на многомиллионные издержки)
      Ну, то есть, навернул костыль вместо того, чтобы родить фундаментальное решение, я правильно понимаю?
      > В итоге что лучше: пожертвовать чуть больше памяти, или сидеть потом офигевать
      Я предлагаю пожертвовать чуть больше мозгов. Ибо вы становитесь заложником LIE # 3:
      cellperformance.beyond3d.com/articles/2008/03/three-big-lies.html
      > все проги сразу писать на ассемблере?
      Проблема ассемблера только в одном: он не переносим между разными аппаратными архитектурами, и под каждую архитектуру придётся писать код по-новому. Для решения этой проблемы был придуман Си.

    • @vladimirsadovnikov3797
      @vladimirsadovnikov3797 3 роки тому

      @@homo-ergaster LIE # 1
      cellperformance.beyond3d.com/articles/2008/03/three-big-lies.html

  • @user-fr5ty2ll2p
    @user-fr5ty2ll2p 3 роки тому

    Очередное классное видео от дяди Серёжи

  • @stmlab149
    @stmlab149 3 роки тому

    Спасибо за видео! Полезно знать

  • @levonminasian6090
    @levonminasian6090 3 роки тому +8

    Сергей, добрый день. Полностью согласен с тем, что вы сказали в видео. Однако всегда интересовал вопрос: почему когда мы пытаемся в Hibernate достать из базы поле с несуществующим id, мы получаем просто null вместо exception? Или таким фреймворкам возвращать null можно?

    • @oshastitko
      @oshastitko 3 місяці тому

      не знаю, как в Hipernate , но в Entity Framework есть метод First(), который вернёт эксепшн, а есть FirstOrDefault(), который вернёт нул. По-моему, логично

  • @yegorsk97
    @yegorsk97 3 роки тому +10

    А если сериализуется JSON и у пользователя есть поле которое не установлено, значение его null

  • @ilyapetrov5628
    @ilyapetrov5628 Рік тому +1

    Хочу добавить, что это вкусовщина и не стоит вовзодить это правило в абсолют, иногда NULL подходит лучше.
    Примеры:
    1. Не найден DSN - дальнейшее выполнение программы не имеет смысла.
    2. Не найден менеджер для клиента - ОК, с этим клиентом пока не работают менеджеры.
    Если в первом случае действительно лучше кинуть исключение, то во втором exception не подходит, так как:
    а) Это не ошибка, а эксепшены обычно кидают в случае ошибок
    б) Exception в данном случае тоже накладывает ограничение на клиентский код, более того он требует более громоздкой формы от клиента - try catch.

  • @user-si4qz6ps9o
    @user-si4qz6ps9o 2 роки тому

    Вообще звучит классно, нужно просто попрактиковаться с таким приемом.

  • @XOTAbGRO
    @XOTAbGRO 3 роки тому +3

    C# 8.0 добавил понятие nullable (ссылочные типы, допускающие значение null) и сделал объекты как бы не допускающими null. И теперь почвилось куча предупреждений в местах, где идёт обращение без проверки на нуль или передача таких значений в методы без это1 поддержки. Стало удобнее. Теперь, если твой метод всё таки может вернуть нуль, то ты добавляешь знак вопроса к имени метода.

  • @TheSyntime
    @TheSyntime 3 роки тому +26

    Логика нарушена. Почему, если возвращается null, то нужно переименовать метод в getStudentOrNull, а если выбрасывается эксепшон, то метод не нужно назвать getStudentOrThrowException?

    • @handleftman
      @handleftman 3 роки тому +1

      по идеи если на метод повесить throws то его не нужно так называть?

    • @redeyes256
      @redeyes256 3 роки тому +1

      Потому что компилятор заставит тебя его явно обработать. А о том, что метод может возвращать Null программист мог не знать или забыть

    • @Gimli_Dwarf
      @Gimli_Dwarf 3 роки тому

      @@redeyes256 чего? Хотя да про указатели оказывается нам уже знать не надо

    • @TheSyntime
      @TheSyntime 3 роки тому

      @@redeyes256 Это к сожалению проблема компиляторов и самих языков, потому что он также должен заставить обработать Null, если он там возможен

    • @redeyes256
      @redeyes256 3 роки тому

      @@Gimli_Dwarf не понял к чему это вообще написано и причем здесь указатели

  • @hrustalevdev
    @hrustalevdev Рік тому

    Хорошее видео. Спасибо!

  • @xxxxxx-kz6yi
    @xxxxxx-kz6yi 3 роки тому +2

    Удачи ! Спасибо.

  • @HybridWarARgungame
    @HybridWarARgungame 3 роки тому +6

    Создавать NullObject это: тратить ресурсы на создание и удаление не нужного обьекта. И все равно по бизнес логике может быть необходимо проверить этот NullObject, пустой он или полный.

  • @xlenchik
    @xlenchik 2 роки тому +3

    каждый чих будем заворачивать в try except, а потом удивляться чего так все тормозит

  • @romanmotovilov129
    @romanmotovilov129 3 роки тому

    Спасибо! Хороший урок!

  • @Lucio11a
    @Lucio11a 3 роки тому +2

    Буду кодить прогу следующую, на ошибку зафигачу "Усе погано!"..)

  • @TeppopucT
    @TeppopucT 3 роки тому +14

    Очень-очень субъективная вкусовщина адептов истинного ООП (особенно в энтерпрайзе).

  • @svetopolk
    @svetopolk 3 роки тому +6

    Серега, переходи на JAVA 3, а именно KOTLIN, в котором узаконили возвращать null, потому что есть nonnull и nullable переменные. Бреслав отдельно подчеркивал, что null в котлине это тоже самое, что Optional.empty() в жаве, только без оберки и следовательно со всех точек зрения бесплатное.
    И не надо оборачивать никакими проверками на null и специально следить, что тебе запихнут в String null не надо (null запихнут только в String?), все на уровне компилятора. Пример:
    val name: String? = null
    val length: Int? = name?.length //тут будет null и можно вызывать у null объекта метод без всякой if (..!=null) обертки
    val length: Int = name?.length ?:0 // а тут ноль, кому не надо nullable переменных, тот и думает про default значение
    val length: Int = name!!.length //а тут выпадет исключение, для любителей кидать и ловить исключения

    • @homo-ergaster
      @homo-ergaster 3 роки тому

      Ээээх. Котлин, конечно, крут. Жаль что вакансий в энтерпрайзе на котлине кот наплакал (

    • @svetopolk
      @svetopolk 3 роки тому

      @@homo-ergaster дописывать и подерживать, конечно надо на JAVA, но все новые микросервисы мы на котлине начинаем. Мне кажется все так.

    • @homo-ergaster
      @homo-ergaster 3 роки тому

      @@svetopolk Ну не все. Если команда на Java и часть ее сопротивляется переходу на Kotlin, то хрен получится новое писать на нем.

    • @svetopolk
      @svetopolk 3 роки тому

      @@homo-ergaster если большая часть команды сопротивляется то действительно не переходят. Только весь вопрос - а сопротивляются ли? Это реальный кейс?

    • @homo-ergaster
      @homo-ergaster 3 роки тому +1

      @@svetopolk ну многие в команде его не знают и им в лом изучать, поэтому против. Потом в качестве IDE используем NetBeans, которая Kotlin не очень хорошо поддерживает, руководство не хочет покупать IDEA.

  • @skbmw530
    @skbmw530 3 роки тому +2

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

  • @dmitryluchkin8424
    @dmitryluchkin8424 3 роки тому

    Здравствуйте Сергей, посмотрел ваше видео про курсы, заинтересовал подход. Посоветуйте, если я знаю core, сталкивался со спрингом, сталкивался с jdbc. Но уверенности в знаниях нет, имеет ли смысл сразу пойти на курс под названием Java EE? Реально ли с не очень большим запасом знаний, потянуть первые задания??

  • @matyev-hcuabg
    @matyev-hcuabg 3 роки тому +5

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

  • @user-rv5gy6mt3x
    @user-rv5gy6mt3x 3 роки тому +24

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

    • @shitposting_box
      @shitposting_box 3 роки тому +3

      Так сказано же, что кидать исключение в случае, если по указанному айдишнику всегда 100% должно вернуться что-то, отличное от null, что в общем-то логично - если метод всегда должен возвращать объект, а не возвращает, то где-то проеб и лучше кинуть исключение

    • @user-rv5gy6mt3x
      @user-rv5gy6mt3x 3 роки тому +8

      @@shitposting_box Ааа, я понял, вместо простого нал, вернуть нал в обертке, может на уровне экспертов это и круто, но у ребят попроще точно все поломается когда они получат объект с нужным интерфейсом, но при этом полностью голый. Что значит "100% всегда что-то вернется "я не уловил, такое может быть только если метод параметров не принимает и всегда одно и тоже возвращает.

    • @user-rv5gy6mt3x
      @user-rv5gy6mt3x 3 роки тому

      Или если это чистая функция, но мы ведь про геттеры.

    • @justkrybik
      @justkrybik 3 роки тому

      @@user-rv5gy6mt3x допустим, мы конструируем объект, скажем, автомобиль. В его конструкторе инициализируем двигатель, но бизнес правилами авто без двигателя не должно существовать... Ставить null и везде в клиентах автомобиля проверять его? Или бросить исключение и ловить его в коде обладающем знаниями о том что с этим исключением делать?

    • @user-rv5gy6mt3x
      @user-rv5gy6mt3x 3 роки тому +5

      @@justkrybik Я не люблю подобные примеры потому как они очень отдаленные, мы говорим не о уровне бизнес требований, а гораздо более мелком, хотя даже здесь я уже заранее знаю что однажды бизнес скажет: "А нет, все таки может быть авто без двигателя когда двигатель на кап ремонт вытащили". Вообще подобные ситуации уже давно решаются тайп хинтами, а мы обсуждаем предложение автора вообще никогда и ни при каких обстоятельствах не возвращать нал.

  • @Fodintsov
    @Fodintsov Рік тому

    Один из немногих русскоговорящих, кто говорит "нал".

  • @rucaua
    @rucaua 3 роки тому +1

    В php (в частности) есть строгая типизация возвращаемых значений, что решает вопрос передачи понимания, что метод может вернуть null. Ну и есть Null coalescing operator. Так что обработка полученного null не тянет кучи кода. В целом я согласен с Вашими выводами, конкретно смущает «никогда» и конкретно для php.

  • @user-eo1vs6mh5m
    @user-eo1vs6mh5m 3 роки тому +6

    Null и undefined можно и нужно возвращать. Но только там где это нужно.

  • @forcharc
    @forcharc 3 роки тому +5

    А если писать на котлине? Есть ли смысл кидать exception, если тип возвращаемых данных заранее тебе говорит, будет null или нет?

    • @nooftube2541
      @nooftube2541 3 роки тому +4

      Нет, конечно. В нормальный языках такой хрени нет :)
      Проблема только если это используются в связке с сырым jvm который плевать хотел на ненулабельность котлина.

    • @it-6411
      @it-6411 3 роки тому

      Alex Smith через рефлекшн записать null в notnull поле)

    • @alexandernifanin7366
      @alexandernifanin7366 3 роки тому

      @@it-6411 так Gson любит делать.)

  • @digitalsocium9638
    @digitalsocium9638 3 роки тому

    хороший канал, спасибо

  • @b3d4zz13
    @b3d4zz13 2 роки тому

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

  • @alexsanruscool
    @alexsanruscool 3 роки тому +6

    Офигеть прервёмся на рекламу. У меня перед твоей рекламой в этот момент вылезло ещё две.

    • @purplep3466
      @purplep3466 3 роки тому

      adblocker

    • @purplep3466
      @purplep3466 3 роки тому

      на всех операционках есть, даже на iPhone спокойно есть способ блочить рекламу

    • @0imax
      @0imax 3 роки тому +1

      Претензии к ютубу - он сам решает, куда и сколько рекламы вставлять.

    • @grommaks
      @grommaks 3 роки тому

      @@0imax Временные метки определяет автор видео, так было года два назад...что то поменялось?

    • @0imax
      @0imax 3 роки тому

      @@grommaks Ты включаешь монетизацию, а ютуб сам решает какую рекламу и в каком количестве ставить. Причём сейчас всё настолько печально, что в зависимости от контента монетизация может быть недоступна, например, если в видео есть просто демонстрация оружия (порой даже страйкбольного) или какая-нибудь жесть, пусть даже это исторические материалы.
      Ну а временнЫе метки, которые под полосой прокрутки - это уже автор делает, но на рекламу это вроде как не влияет.

  • @mtokurow
    @mtokurow 3 роки тому +3

    A как же стандартный JPA? Он-то как раз возвращает NULL, если в методе findById я впишу несуществующий ID, без всяких исключений и null object-ов.
    Или просто «quod licet Jovis non licet bovis»? :D

    • @MikhailKolesnikov
      @MikhailKolesnikov 3 роки тому

      Файнд и Гет -- как бы намекают, что они про разное…

  • @LerooryJenkins
    @LerooryJenkins Рік тому +1

    Очень классные и информативные видео, спасибо! Только смотрят их не только опытные разработчики, но и люди с маленьким опытом. В связи с чем было бы ещё круче вставлять, хотя бы, скрины с примерами кода для визуального понимания.

    • @vladimirblagin3105
      @vladimirblagin3105 Рік тому

      Если бы там были скрины, было бы не все так однозначно :-)

  • @user-tt3qw2zg7d
    @user-tt3qw2zg7d 3 роки тому +2

    Окей, но чем тогда отличается возвращение null от выбрасывания исключения в тех кейсах когда программа должна продолжить свою работу
    Например аутентификация когда мы пытаемяся найти пользователя с определённым юзернеймом и от того, есть ли такой пользователь зависят дальнейшие действия , получается что вызывающий кот все равно должен обработать ситуацию только уже не с null, а с перехватлм исключения

  • @vad6525
    @vad6525 3 роки тому +3

    Приемлемо ли тогда иметь метод Find, который будет возвращать null? Например repository.FindById(20) возвращает null если данные не найдены. Конструкция простая и не вижу смысла ее усложнять.

    • @iShredar
      @iShredar 3 роки тому

      Ты неверно понимаешь нэйминг. Если ты пытаешься получить что-то по уникальному полю, который определяется внутри вашей системы, то это всегда Get, иначе как вы смогли получить это что-то уникальное (например ID), если его ещё нет в системе. Если ты пишешь слово Find - то это должен быть поиск по не уникальным полям, а значит результатом будет коллекция. В случае если ничего не найдено, то это пустая коллекция. Единственный вариант с null - это поиск по уникальному внешнему ключу, который задаётся не вашей системой (например FindByExternalKey; Самый простор пример - это номер вашего паспорта, он уникален, но не вы создаёте/задаёте его, но вам нужно проверить зарегистрирован ли человек с таким номером паспорта у вас..). В данном случае вы пытаетесь проверить существует ли сведения о неком внешнем (не вашем) бизнес объекте, и этот случай близок к тому случаю, когда в видео говорилось что null допускается перед первым созданием объекта в некоторых архитектурных решениях.

    • @vad6525
      @vad6525 3 роки тому +1

      ​@@iShredar Любой ID может быть удален со временем, но остаться в логах или прилететь по api. Некоторые таблицы чистятся, за ненадобностью. ID может быть введен пользователем с UI при поиске. В этом случае он вполне может отсутствовать, так как пользователь может ошибиться.
      Не понятен пример про возврат пустой коллекции, я же спрашивал про repository.FindById, а не про Find

    • @iShredar
      @iShredar 3 роки тому

      ​@@vad6525 Если вопрос был именно про repository (или любой слой, который работает с хранением данных), то стоило это указать сразу в вопросе, а не в примере. В таком слое нэйминг является больше договорённостью внутри команды, но как правило он соответствует тому что используется в Business терминах/правилах. Такой слой доступа данных - это просто прослойка, предоставляющая данные из хранилища в понятном виде для вашего приложения. В таком случае, я считаю вполне нормально получить null для одиночного объекта, так как по сути его вернёт ваша база. Но этот слой не должен быть доступен напрямую с вашего UI, то есть между UI слоем и слоем предоставления данных (repository ) должна быть прослойка, которая преобразует эти "сырые" данные, в вид соответствующий Business терминам/правилам. И вот тут уже null не допустим. Если вы что-то запрашиваете по ID то, что было удалено или не существует вовсе - исключение. Осталось что-то в логах? - логи не часть приложения или бизнеса, логи это побочный продукт жизнедеятельности, для них свои правила работы;
      может прилететь по api? - проблема с архитектурой (не берём случаи, когда данные обрабатывались в некоторой задаче в момент удаления, тут банальное исключение)
      "Не понятен пример про возврат пустой коллекции"
      пусть нужно выполнить поиск по неуникальному полю, например FindStudentsByName, даже если ничего не найдено, не стоит возвращать null, правильно будет вернуть пустую коллекцию, что-то вроде new List ();

  • @Narryel
    @Narryel 3 роки тому +32

    20:17 то есть возвращать бизнес невалидный обьект? мдаааааааа, fail-fast как говорится

    • @justkrybik
      @justkrybik 3 роки тому +2

      А с чего вдруг, в озвученном случае, это невалидный объект? Видимо давлением газов рвущегося пукана уши заложило...

    • @systemify
      @systemify 3 роки тому +2

      Потому что проверить возвращаемое значение проще, чем проверять поля этого значения

    • @sergeykhairulin
      @sergeykhairulin 3 роки тому

      а потом мы еще этот объект мутировать будем, красота.

  • @BrodrickStreams
    @BrodrickStreams 3 роки тому

    А вот такой вопрос - я юзаю apache http и метод получения респонса требует обернуть его в трайкетч. А мне, собственно, нужно вернуть json который я беру из респонса. Соответственно объявлять json мне приходится вне трайкетча налом. Как будет правильно поступить в таком случае? Или кидать рантайм эксепшен в трайкетче где я отправляю запрос и получаю респонс - это нормально?

  • @bathduckwastaken
    @bathduckwastaken 3 роки тому +2

    Смотрю вас уже второй год, качество роликов заметно выросло, так держать!

  • @tony-the-fox42
    @tony-the-fox42 3 роки тому +3

    Почему бы не возвращать какой-нибудь Optional тип, у которого будет свойство HasValue в значении True, если в Optional есть экземпляр нашего T, и False если нет? По моему идеальная вещь

    • @Jdivanchik
      @Jdivanchik 2 роки тому

      В тех случаях, где есть вероятность вернуть null да.

  • @user-uq9yf3xq3q
    @user-uq9yf3xq3q 3 роки тому +22

    рубисты молчать)0

  • @daniilpalii6743
    @daniilpalii6743 3 роки тому

    Что скажете про добавление методов `bool Exists(int id)` или `bool TryGet(int id, out Student student)`?

  • @alexeyolshevskiy1358
    @alexeyolshevskiy1358 3 роки тому

    Сергей как обойти ситуацию с null, если зависимости от того найден один или несколько обьектов зависит бизнес логика?

  • @me2beats313
    @me2beats313 3 роки тому +17

    есть класс Person
    ему сколько-то лет
    поле age
    но сколько - неизвестно
    значит оно == null
    null просто сообщает, что возраст на данный момент не определен (и это правда).
    это реальная, жизненная ситуация, ведь мы можем знать имя человека, но не знать его возраста.
    поэтому в любом случае нужно каким-то образом обрабатывать ситуацию, когда возраст ещё неизвестен, но мы уже что-то хотим с ним делать.
    и null кмк удобный и лаконичный способ для этого
    никогда не имел серьезных проблем с этим (хотя может потому, что не пишу на jаva?)

    • @jelooJusta
      @jelooJusta 3 роки тому

      твой пример ничего общего с видео не имеет. Там про возврат null из метода, а не о свойстве обьекта, хотя в описанном случае практичнее указать age: -1

    • @AnatolyPashmorha
      @AnatolyPashmorha 3 роки тому

      по классике тебе нужно создать новый ValueObject Age со значением Undefined каким-то. Ну, или Optional можно использовать. Вобще, это правильно, но не практично зачастую. Хотя, в видео речь больше об объектах (Person), а Age это все-таки Value, несколько иная сущность.

    • @user-bs6qw5gr1o
      @user-bs6qw5gr1o 3 роки тому

      @@jelooJusta Чем getProperty() не метод?

    • @user-bs6qw5gr1o
      @user-bs6qw5gr1o 3 роки тому +2

      @@jelooJusta Возраст age==0 обманывает. Мы должны помнить, что 0 подразумевает отсутствие.

    • @user-bs6qw5gr1o
      @user-bs6qw5gr1o 3 роки тому +1

      @@AnatolyPashmorha В видео вообще запрещается возвращать NULL, в любом случае

  • @user-se1nh2cn2y
    @user-se1nh2cn2y 3 роки тому +13

    Иногда возвращать null - нормально, иногда выкидывать exception - нормально, а иногда дефолтные объекты возвращать тоже норм :) Нужно от бизнес-логики идти. Думаю, нужно видео с противоположными аргументами "Почему нужно возвращать NULL?", ну чтобы всесторонне тему разобрать, за и против) а то пока только с одной стороны) не хватает взгляда с двух сторон, это как у нормальных журналистов, которые с разных сторон вопрос освещают

  • @lexlotar4847
    @lexlotar4847 3 роки тому

    А можно рассказать о вариантах решения проблемы? По факту получается нужно весь вызывающий код оборачивать в try catch. А много кто говорил , что эт прям тоже не очень. И чем по ресурсоемкости отличается проверка на null и прерывание по try catch. Допустим я вибираю метод Single, и например по любой фигне, которую вбил пользователь кидается exception. Разве это также не накладывает ограничений на вызывающий код?

  • @ztepler
    @ztepler 3 роки тому +1

    Возможно мой вопрос чуть-чуть мимо темы, но я его очень хочу задать. Данный вопрос тесно связан с типами Python. Данный вопрос про "отсутствие значения" (None или NaN). Вероятно None и NULL это разные сущности, между ними явно есть отличия, но мне кажется в текущем контексте это похожие штуки.
    Что можно делать в том случае, когда какие-то части объекта могут иметь пустые (None) значения? То есть если наличие None (отсутствие значения) - это валидное состояние какого-то поля объекта, предусмотренное бизнес логикой? Такой кейс как раз приводит к этим проблемам что всё время нужно проверять, не является ли эта часть объекта None, но как этого избежать, если это часть бизнес задачи, мне непонятно. При это нельзя установить этот объект в дефолтное состояние, нужно контроллировать что в нём нет значения (иначе, например, при агрегации данных дефолтное значение будет искажать реальную картину).
    Может быть есть какие-то бест-практики? Может быть лучше для этого иметь какой-то специализированный объект (тот же самый numpy.nan?). Наверное как раз те самые None и NaN это и есть некоторая форма того самого NullObject, просто без дефолтного значения?

  • @KybaLioN66
    @KybaLioN66 3 роки тому +10

    нельзя использовать NULL, это потому что у вас JAVA головново мозга. Если бы был С++
    головново мозга то и NULL можно было использовать с assertions.

    • @KybaLioN66
      @KybaLioN66 3 роки тому +5

      разработчики таких языков как Java или С# кроме языка ни о чём не думают. Как это будет работать по производительности ?.
      Ни накладывают ли исключение дополнительные расходы ? и тд. Скажем вы когда нибуть думали что если в язык С дабавят
      искючения и скажем в едре Линукс изменять все коды вызврата на исключения. Ну ответь очевидно. Я думаю может конкретно
      в Java возвращять NULL это плохо (или С#). Видео должно было называться "Почему нельзя возвращать NULL в Java ?"

    • @Salabar_
      @Salabar_ 3 роки тому +1

      В плюсах можно возвращать объекты по значению и ссылки не могут быть NULL. Там этой проблемы не возникает.

    • @V_ft
      @V_ft 3 роки тому

      @@Salabar_ а объекты, созданные с помощью new?
      Он же и говорит о случаях, когда не юзаются умные указатели

    • @Salabar_
      @Salabar_ 3 роки тому

      ​@@V_ft Видос именно о неопределенности в интерфейсе функций. Если функция возвращает указатель, то ты всегда проверяешь его на NULL, даже если кажется, что такого не бывает. Потому что так принято. И это не так сильно бесит, потому что есть value-типы и ссылки, которые и используются в 95% функций. В Джаве же ты не можешь по сигнатуре понять, может она сломаться или нет: ты либо проверяешь буквально каждую строчку, либо ловишь NRE, либо так, как описано в видосе.

  • @alexkononenko4862
    @alexkononenko4862 3 роки тому +4

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

  • @artemgoncharuk5174
    @artemgoncharuk5174 2 роки тому +2

    В JS (и не только) есть конструкция optional chaining которая прекрасно решает эту проблему. Object?.method?.() ?? ; вуаля, поведение аналогично паттерну NullObject ничего не произойдет и ошибки не будет. Так или иначе, что бы мы ни использовали всегда есть плата в виде каких-то проверок или перехватчиков, мы в любом случае не можем игнорировать отсутствие объекта в результате, это кейс который должен быть обработан, чем бы результат не являлся и какой бы паттерн мы не применили. Чтобы программисту было понятно что метод может вернуть null хорошо использовать аннотации и IDE которые могут это показать. Не вижу ничего страшного в современных языках использовать null, большинство решило эту проблему и умеет работать с null корректно.

  • @KO7MO7
    @KO7MO7 3 роки тому

    Очень интересное идея для замены null- возвращаться деф. значения. Вроде все банально, а сам не задумывался.

  • @user-tb2jf7km2m
    @user-tb2jf7km2m 3 роки тому +3

    Исключения на многих языках вроде как довольно дорогая ситуация, поэтому наверное не все следует реализовывать с помощью них. Но так конечно автор прав. Вообще в языках должно быть уже прямое указание, что там null быть не может, как в Swift.

    • @robotE13
      @robotE13 9 місяців тому

      Неважно дорогая или нет. На мой взгляд, тут другое ограничение. Исключения надо использовать только как исключения... сюрприз, да? То есть когда произошла реально ненормальная ситуация (ну например идет попытка активации несуществующей учетки, или БД недоступна, или чтение из файла завершилось ошибкой и т п). БЛ же на них строить - чистой воды безумие.

    • @torburgmax
      @torburgmax 5 місяців тому

      @@robotE13 вот соглашусь. и глобально контракт нам говорит, может ли объект вернуть нал или ошибку. поэтому с этой точки зрения вообще никакой разницы нет, ошибку обработать только "дороже" с точки зрения написания кода

  • @WalkHB2
    @WalkHB2 3 роки тому +5

    Полезное видео.
    К сожалению, "вершиной" программирования считается применение паттернов, при чем в таком формате, что чем больше паттернов использовал при написании модуля N - тем лучше.
    А вот об умении писать код без null, об умении писать код с минимальным количеством if (когда код не витвится на 100500 вариантов, а "течет" по одному маршруту) - почти никто не говорит.
    Ну и написание нескольких слоев авто-тестов (юнит, приемочные, интеграционные) должно быть по умолчанию, но, к сожалению, не везде они есть, и далеко не везде они покрывают весь функционал.

  • @user-pc5ww4mp4v
    @user-pc5ww4mp4v Рік тому +1

    По-моему, прекрасно все упомянутые проблемы решены в Kotlin:
    - явное именование методов, например listOf(1, 2, 3).firstOrNull { it > 2 }
    - Null-safety: вы всегда твёрдо знаете (если речь не идёт о легаси-библиотеке) и вынуждены это учитывать, где может быть null, а где -- нет
    - Изящные синтаксические конструкции для обработки null'ов, вроде Elvis Operator.

  • @mykola_ch
    @mykola_ch 3 роки тому

    а если возвращать к примеру new Student(), это же объект который равный null, но но все же) так тоже не надо, или это что-то меняет?

  • @alsu666
    @alsu666 3 роки тому +3

    Складывается впечатление, что чел не читает документацию к чужому коду.

  • @MrTheMaks
    @MrTheMaks 3 роки тому +50

    Думал раз затрагиваем тему NUll, то стоит сказать и об использовании Optional, но Сергей решил его проигнорировать.

    • @playerkilleryakutia9415
      @playerkilleryakutia9415 3 роки тому

      Это что-то типа из разряда Enum?

    • @MrTheMaks
      @MrTheMaks 3 роки тому

      PlayerKiller Yakutia это надстройка над null. Вы можете на ютубе к примеру вбить и узнаете больше.

    • @BtXFWkyZBtXFWkyZ
      @BtXFWkyZBtXFWkyZ 3 роки тому +13

      Он же сказад про wrapper-классы (Future, Optional) как первый вариант

    • @MrTheMaks
      @MrTheMaks 3 роки тому

      Hamster Go получается я пропустил. Тогда извиняюсь.

    • @protiv_bio
      @protiv_bio 3 роки тому

      @@GK-tw7nu конечно можно, ты ведь возвращаешь не null, а обертку, из которой ты не прочитаешь значение без get(), а get() нормальный программист без проверки делать не будет. Тут хоть бейся головой об стену, не забудешь проверить))

  • @mike_mi_mike
    @mike_mi_mike 3 роки тому

    Так что насчёт optional? Использовать его как альтернативу возврата null и паттерна Null Object?

  • @hihi-hehe
    @hihi-hehe 3 роки тому

    В официальной WIN API везде возвращается NULL и есть отдельный метод GetLastError(), который объясняет ошибку.
    Это плохая практика?
    И что делать в коде написаном на С?

  • @Guitarist138
    @Guitarist138 3 роки тому +13

    А как же быть с null в БД? Али переводить всё на not null, дабы, не дайте боги, не написать лишнюю проверку?

    • @protiv_bio
      @protiv_bio 3 роки тому +1

      Зависит от логики. Зачем null в БД, для полиморфизма? Тогда hibernate на себя берет ответственность следить за этими полями. Если бизнес-значение может быть null, тогда можно обернуть в Optional/кидать runtime exception на геттере поля, при этом в throws его еще указать.

    • @qr46654
      @qr46654 3 роки тому

      Вернуть объект с пустыми полями?

    • @stormvoid7017
      @stormvoid7017 3 роки тому +3

      @@protiv_bio >обернуть в optional
      Чтобы получить nullpointer, но с другим названием 😂

    • @protiv_bio
      @protiv_bio 3 роки тому +3

      @@stormvoid7017 когда ты получаешь optional и не проверяешь его, это как минимум странно. Когда ты получаешь Object, ты рассчитываешь, что там лежит object. Таковы правила, и не я их придумал.

    • @Guitarist138
      @Guitarist138 3 роки тому +5

      @@protiv_bio то есть проверять не равенство null`у, а что там скажет isPresent? Великолепная логика. Меняем одну проверку на другую.

  • @NizZerbergmaN
    @NizZerbergmaN 3 роки тому +12

    "Nooone " прошипел python и уполз под корягу.

    • @justkrybik
      @justkrybik 3 роки тому

      А есть ли разница? Стол или table?

  • @thegamerrandomer
    @thegamerrandomer 18 днів тому

    Если завтра не сдам финальный экзамен, то в этом году вместо diplom верну домой null

  • @LosashExote
    @LosashExote 3 роки тому

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

  • @samuro2ua
    @samuro2ua 3 роки тому +17

    Сергей, спасибо! Расскажи о тестировании для не тестировщиков. Какие виды тестов бывают? В каких случаях обязательно тестировать код, когда отложить на потом? И т. д.

    • @mdfitumi
      @mdfitumi 3 роки тому +5

      Я не Сергей, но отвечу
      Самый базовый вид тестов - unit тесты. Ими тестирую функционал в пределах класса или модуля. Есть методология TDD, при которой сначала пишутся тесты, а потом под них подгоняется код (до его готовности). Писать или нет зависит от проекта, если вы работаете один, над небольшим проектом, то написанием тестов сильно усложните себе жизнь. С ростом проекта, в геометрической прогрессии возрастает шанс появления ошибок и регрессий, при внесении нового функционала. В таком сценарии наличие тестов сыграет вам на руку и позволит гораздо быстрее находить ошибки.

    • @mdfitumi
      @mdfitumi 3 роки тому +2

      P.S. Написание качественных/несущих пользу тестов, требует качественного кода.

  • @maxlich9139
    @maxlich9139 3 роки тому +8

    Для обработки null-ов сейчас в джаве, кстати, есть Optional-ы и Stream-ы. И при этом если ты работаешь с Optional-ами и Stream-ами, то чаще всего удобнее, когда из методов возвращаются null-ы, а не кидаются эксепшены (тем более - проверяемые).

    • @user-gc3lm8pi2v
      @user-gc3lm8pi2v Рік тому

      ResponseEntity с обработкой null-ов это вообще спокойная тема

    • @maxlich9139
      @maxlich9139 Рік тому

      @@user-gc3lm8pi2v это что? Spring web mvc?

    • @user-gc3lm8pi2v
      @user-gc3lm8pi2v Рік тому

      @@maxlich9139 ага

    • @maxlich9139
      @maxlich9139 Рік тому

      @@user-gc3lm8pi2v А ну это другое, понимать надо
      ))))

  • @kyleRQWS
    @kyleRQWS 2 роки тому +1

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

  • @Riodevista
    @Riodevista 3 роки тому

    видео пока не посмотрел, но как программист заочно возмутился неплохо так

  • @viv81ster
    @viv81ster 3 роки тому +6

    В magento возвращался null object и это хуже null
    потому что ты ожидаешь что вернулся кастомер какой-то по id и а у тебя пустой объект побежал по системе

    • @lyloo6577
      @lyloo6577 3 роки тому +3

      хрен редьки не слаще, либо обвешиваешь все проверками на null, либо на null object )

    • @sevkakovalchuk7672
      @sevkakovalchuk7672 3 роки тому

      Это в какой Magento? В Magento-2 репозитории выбрасывают NoSuchEntityException, если пробовать достать несуществующий объект по ID или другому идентифицирующему полю (например email для кастомера). Если getList делать с searchCriteria, то всегда объект возвращается, но я не бы не назвал его NULL-объектом. Если ничего не найдено, то у него просто будет пустой массив items.

    • @viv81ster
      @viv81ster 3 роки тому

      @@sevkakovalchuk7672
      Вот под рукой 2.3.3 но в более ранних тоже самое
      \Magento\Cms\Model\PageRepository
      public function getById($pageId)
      \Magento\Customer\Api\CustomerRepositoryInterface
      /**
      * Retrieve customer.
      *
      * @param string $email
      * @param int|null $websiteId
      * @return \Magento\Customer\Api\Data\CustomerInterface
      * @throws \Magento\Framework\Exception\NoSuchEntityException If customer with the specified email does not exist.
      * @throws \Magento\Framework\Exception\LocalizedException
      */
      public function get($email, $websiteId = null);
      Да их полно

    • @sevkakovalchuk7672
      @sevkakovalchuk7672 3 роки тому

      @@viv81ster не понимаю Вас. Вот метод:
      /**
      * Load Page data by given Page Identity
      *
      * @param string $pageId
      * @return Page
      * @throws \Magento\Framework\Exception\NoSuchEntityException
      */
      public function getById($pageId)
      {
      $page = $this->pageFactory->create();
      $page->load($pageId);
      if (!$page->getId()) {
      throw new NoSuchEntityException(__('The CMS page with the "%1" ID doesn\'t exist.', $pageId));
      }
      return $page;
      }
      он выбрасывает исключение. Так же как и CustomerRepository, это видно даже в заголовке у вас в комменте:
      @throws \Magento\Framework\Exception\NoSuchEntityException If customer with the specified email does not exist.
      Или вы про методы типа load()? Ну этот подход давно deprecated. Так же как и метод save(). Для загрузки и сохранения надо использовать Repository. Factory применяется когда надо создать новый объект, но в таком случае вам не надо делать load обычно.

    • @viv81ster
      @viv81ster 3 роки тому

      @@sevkakovalchuk7672 Возвращался, там стоит прошедшее в первой так точно
      Сейчас там переделали все
      Сорри я посмотрел на ваш вопрос и не понял.

  • @dubovikovpv
    @dubovikovpv 3 роки тому +5

    Обработка эксепшена гораздо дороже проверки на null

    • @0imax
      @0imax 3 роки тому

      Паттерн "преждевременная оптимизация" передаёт привет.

    • @vladgonchar
      @vladgonchar 3 роки тому

      @@0imax преждевременные роды передают привет

    • @0imax
      @0imax 3 роки тому

      @@vladgonchar сочувствую.

  • @kprohorow
    @kprohorow Рік тому

    Выглядываю на улицу а там полна площадь людей с плакатами "Верните NULL!" и "Свободу Анжеле Дэвис" 🤣

  • @alexthunderrex
    @alexthunderrex 10 місяців тому

    А данное утверждение актуально например для работы в Unreal Engine? Если я возвращаю nullptr, когда нет например персонажа по указателю 🤔