Support us

4 рекомендации бывшего разработчика LinkedIn, который сделал 1000 код-ревью

6 комментариев
4 рекомендации бывшего разработчика LinkedIn, который сделал 1000 код-ревью

В блоге на Hacker Noon бывший разработчик LinkedIn Стивен Хейдел собрал 4 рекомендации, которые ему приходилось давать наиболее часто при выполнении проверок кода в компании. dev.by публикует перевод статьи.

Рекомендация 1: выбрасывать исключения, когда что-то идёт не так

Вот типичный паттерн, который я наблюдал:

Этот паттерн приводил к сбоям в одном из мобильных приложений, с которым я работал. Поиск на стороне сервера, который мы использовали, начал бросать исключения. Но в серверном API приложения был код, подобный тому, что приведён выше. Поэтому приложение получало ответ об успешном выполнении «200», а пользователю выдавало пустой список по всем до единого поисковым запросам.

Если бы вместо этого API выбросил исключение, наши системы мониторинга мгновенно обнаружили бы его и исправили.

Очень часто возникает желание просто вернуть пустой объект, когда приложение поймало исключение. Примеры пустых объектов в Java — Optional.empty(), null и пустой список, а сделать это больше всего хочется при парсинге URL. Если парсить URL-адрес из строки не получается, то следует не возвращать null, а задаться вопросом: почему URL неверен и не имеет ли место проблема с данными, которую нужно исправлять на более высоком уровне.

В таких случаях пустые объекты — не лучшее средство. Если ситуация исключительная, нужно выбрасывать исключение.

Рекомендация 2: использовать самый специфический тип из возможных

Этот совет — противоположность антипаттерна «строковой типизации». Зачастую я вижу вот такие примеры кода:

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

Вопрос: почему программисты с самыми добрыми намерениями пишут плохой код со строковой типизацией? Ответ: потому что внешний мир не сильно типизирован. Есть много разных мест, где можно найти строки:

  • параметры запроса и пути в URL;
  • JSON;
  • базы данных, не поддерживающие перечисление;
  • плохо написанные библиотеки.

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

Это даёт ряд преимуществ, например позволяет сразу найти проблемные данные, а в случае ошибки приложение упадёт на ранних этапах. А также не понадобится отлавливать исключения по всему приложению, если данные заранее проверены. Кроме того, сильная типизация обеспечивает более наглядные сигнатуры методов, поэтому не нужно писать такое количество javadoc-ов по каждому методу.

Рекомендация 3: использовать Optional вместо null

Одна из самых лучших особенностей 8 версии Java — класс Optional. Он представляет собой объект, который может существовать или не существовать.

Вопрос: какое единственное исключение имеет свою аббревиатуру? Ответ: NPE, или Null Pointer Exception. Это самое популярное исключение в Java, которое обходится в миллиарды долларов.

Optional позволяет полностью избавиться от NPE в программе. Однако этот класс нужно применять корректно. Вот несколько замечаний:

  • Не следует просто вызывать .get() каждый раз, когда есть Optional, чтобы использовать его. Вместо этого нужно хорошо подумать о том случае, когда Optional отсутствует, и придумать оптимальное значение по умолчанию.
  • Если такого оптимального значения ещё нет, методы .map() и .flatMap() дадут возможность сделать выбор позже.
  • Если внешняя библиотека возвращает null, нужно сразу обернуть значение, используя Optional.ofNullable(). Такое обычно возникает внутри программ, поэтому лучше предотвратить это в самом начале.
  • Следует использовать Optional в типах возвращаемого значения методов, потому что тогда не нужно читать javadoc, чтобы разобраться, допустимо ли отсутствующее значение.

Рекомендация 4: «unlift» методов при возможности

Лучше избегать методов, которые выглядят вот так:

У всех этих методов есть одно сходство: они используют контейнеры, например Optional, List или Task, в качестве параметров метода. Ещё хуже, если тип возвращаемого значения является тем же контейнером (то есть метод с одним параметром берёт Optional и возвращает Optional). Потому что

1) Promise<A> method(Promise<B> param)

менее гибко, чем просто

2) A method(B param).

Когда есть Promise<B>, можно использовать первый вариант или же второй, «подняв» (lifting) функцию с помощью .map (то есть promise.map(method)).

Однако если есть только В, можно запросто использовать второй способ, а первый — нельзя, поэтому второй способ более универсален.

Я называю этот способ «unlifting», потому что он противоположен распространённому служебному методу lift. Эти корректировки сделают методы более гибкими и простыми в использовании при вызове.

Читайте также
Профессии, которые меняет ИИ, дорожают больше тех, которые не меняет
Профессии, которые меняет ИИ, дорожают больше тех, которые не меняет
Профессии, которые меняет ИИ, дорожают больше тех, которые не меняет
«Вайбы давно позади»: CEO Lovable объяснил, кто должен делать софт
«Вайбы давно позади»: CEO Lovable объяснил, кто должен делать софт
«Вайбы давно позади»: CEO Lovable объяснил, кто должен делать софт
Три в одном: глава ИИ в EY заявил о слиянии инженерных профессий
Три в одном: глава ИИ в EY заявил о слиянии инженерных профессий
Три в одном: глава ИИ в EY заявил о слиянии инженерных профессий
Половина одобренного бенчмарками ИИ-кода не прошла ручного код-ревью
Половина одобренного бенчмарками ИИ-кода не прошла ручного код-ревью
Половина одобренного бенчмарками ИИ-кода не прошла ручного код-ревью

Хотите сообщить важную новость? Свяжитесь с редакцией через страницу контактов

Главные события и полезные ссылки в нашем Telegram-канале

Абмеркаванне
Каментуйце без абмежаванняў

Рэлацыраваліся? Цяпер вы можаце каментаваць без верыфікацыі акаўнта.

Каментарыяў пакуль няма.