65 айтишников задержаны.
33 — неизвестно где.
21 вышли на свободу.

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. Эти корректировки сделают методы более гибкими и простыми в использовании при вызове.

Хотите сообщить важную новость?

Пишите в наш Телеграм

Читайте также

«Почему разработчики участвуют в этом цирке?». Хайринг как главный баг ИТ-индустрии
«Почему разработчики участвуют в этом цирке?». Хайринг как главный баг ИТ-индустрии
«Почему разработчики участвуют в этом цирке?». Хайринг как главный баг ИТ-индустрии
Австралийский разработчик и CTO Нейл Сайнсбари в ужасе от того, как собеседуют и принимают на работу технических специалистов. Публикуем перевод его колонки.
29 комментариев
HackerEarth: Go снова назван самым востребованным языком среди программистов
HackerEarth: Go снова назван самым востребованным языком среди программистов
HackerEarth: Go снова назван самым востребованным языком среди программистов
20 вещей, которые я вынес за 20 лет в программировании
20 вещей, которые я вынес за 20 лет в программировании
20 вещей, которые я вынес за 20 лет в программировании
Программист Schibsted Алекс Эвелёф в блоге на Medium рассказал о главных правилах и принципах, которые вывел для себя за многие годы работы в ИТ. Публикуем перевод статьи.
12 комментариев
Amazon анонсировала новый ML-инструмент для автоматизации проверки кода
Amazon анонсировала новый ML-инструмент для автоматизации проверки кода
Amazon анонсировала новый ML-инструмент для автоматизации проверки кода

Обсуждение

Anonymous
Anonymous
0

Как-то многие советы завязаны на Enterprise и Java.
Если перенести их на, скажем, мобильные приложения, то 1й совет будет хорош, только когда приложение ещё на этапе разработки ("падение" действительно быстро подскажет, где что-то не так). Однако, если у него уже большая активная аудитория, то вернуть пустой список будет однозначно лучше, чем "упасть".

0

Ну что возращать зависит от специфики приложения. Можно и пустой список конечно, но перед этим залогировать ошибку в error log с нотификацией по емайл. Это будет наиболее полное решение.

0

Я бы не был так однозначен даже в случае мобильного приложения. Сравните 2 кейса:
1. приложение падает, это моментально видно всей команде в крашрепорт системе (например fabric) , все знают о этом краше. Если он серьезный, то делаем хотфикс, спустя несколько дней хотфикс расползся по юзерам, проблема решена.
2. Приложение втихую гасит ошибку, приложение делает хорошую мину при плохой игре, приложение находится в противоречивом состоянии, юзер экспириенс страдает, пользователь видит неадекватное поведение (тот же пустой список саджестов при вводе строки поиска), он недоволен. Хорошо еще если он отпишет в саппорт о проблеме или опишет ее в отзыве (нет, он в 95% случаев это не сделает), а скорее всего просто молча выставит плохой рейтинг, а после критического количества подобных проблем просто перестанет пользоваться приложением. Команда может не знать о этой проблеме очень долго.

Пожалуй, я выберу вариант 1.

0

Полезный материал, полезный опыт "с полей".

0

1000 code review это не особо много, особенно, если continuous integration используется. Эти рекомендации присутствуют тем или иным образом в LinkedIn coding style?

0

Советы хорошие, но их 3. Перечитываю дядюшку Боба, там таких советов в десятки раз больше, ментальный проф-экстаз.

Спасибо! 

Получать рассылки dev.by про белорусское ИТ

Что-то пошло не так. Попробуйте позже