Code Review в Java: что проверять и как давать обраттную связь на практике

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Code Review в Java: что проверять и как давать обратную связь на практике

Code Review (ревью кода) — это систематическая проверка чужого кода с целью выявления ошибок, улучшения качества и обмена знаниями. В Java-разработке это особенно важно из-за строгой типизации, особенностей многопоточности и требований к производительности. Однако многие разработчики сводят ревью к простой проверке стиля или, наоборот, превращают его в токсичную критику. В этой статье мы разберём, что именно нужно проверять в Java-коде и как давать обратную связь, чтобы она приносила пользу, а не боль.

1. Что проверять в Java-коде: чек-лист для ревьювера

Чтобы ревью было эффективным, нужно смотреть не только на синтаксис, но и на архитектуру, безопасность и производительность. Вот основные категории, которые стоит проверять.

1.1 Архитектура и дизайн

  • Принципы SOLID: не нарушает ли класс принцип единственной ответственности? Не превращается ли интерфейс в «божественный объект»?
  • Связность и связанность: классы должны быть слабо связаны (loose coupling) и иметь высокую внутреннюю связность (high cohesion).
  • Использование паттернов: оправдано ли применение сложных паттернов? Иногда простой if-else лучше, чем фабрика с десятком классов.
// Плохо: класс делает всё сразу
public class ReportService {
    public void generateReport() { /* генерация */ }
    public void sendEmail() { /* отправка */ }
    public void saveToDatabase() { /* сохранение */ }
}

// Хорошо: разделение ответственности
public class ReportGenerator { ... }
public class EmailSender { ... }
public class ReportRepository { ... }

1.2 Обработка исключений и ошибок

  • Подавление исключений: нельзя писать пустой catch (Exception e) — это скрывает ошибки.
  • Специфичность: ловите конкретные исключения, а не Exception или Throwable.
  • Логирование: исключения должны логироваться с достаточным контекстом (стек-трейс, входные данные).
// Плохо: проглатывание исключения
try {
    processFile(file);
} catch (Exception e) {
    // ничего не делаем
}

// Хорошо: логирование и проброс
try {
    processFile(file);
} catch (IOException e) {
    log.error("Ошибка при обработке файла: {}", file, e);
    throw new ProcessingException("Не удалось обработать файл", e);
}

1.3 Производительность и память

  • Избыточные операции: создание объектов в циклах, ненужные копии строк через new String().
  • Использование коллекций: правильно ли выбран тип (ArrayList vs LinkedList)? Есть ли лишние синхронизации?
  • Stream API: не ухудшает ли стрим читаемость? Иногда обычный цикл понятнее.
// Плохо: создание строки в цикле
String result = "";
for (String s : list) {
    result += s; // каждый раз новая строка
}

// Хорошо: StringBuilder
StringBuilder sb = new StringBuilder();
for (String s : list) {
    sb.append(s);
}

1.4 Многопоточность и синхронизация

  • Правильное использование synchronized: не заблокирован ли слишком большой участок кода?
  • Concurrent collections: используете ли ConcurrentHashMap вместо хэш-таблицы с внешней синхронизацией?
  • Deadlock-опасность: не блокируются ли ресурсы в разном порядке?
// Риск дедлока
synchronized (lockA) {
    synchronized (lockB) { ... }
}
// В другом потоке:
synchronized (lockB) {
    synchronized (lockA) { ... }
}

2. Как писать код для удобного ревью

Хороший ревью начинается с хорошего кода. Автор должен облегчить работу ревьюверу.

  • Маленькие коммиты: один коммит — одно изменение. Не смешивайте рефакторинг с новой функциональностью.
  • Понятные названия: метод processData() — плохо. validateUserInput() — хорошо.
  • Комментарии к сложным местам: если код неочевиден, добавьте пояснение (но лучше упростите код).
  • Добавьте описание к PR: что делает этот код, какие побочные эффекты, что тестировалось.
// Плохое название метода
public void doStuff(List<String> items) { ... }

// Хорошее название
public List<String> filterActiveUsers(List<String> userIds) { ... }

3. Как давать обратную связь: конструктивная критика

Самая частая ошибка — писать «этот код ужасен» или «всё переделать». Такая критика демотивирует и не даёт полезной информации.

3.1 Правило «Сэндвича»

Начните с позитива, затем укажите на проблемы, закончите поддержкой.

  • Хорошо: «Отличная идея вынести логику в отдельный класс! Однако здесь есть потенциальная проблема с потоками. Давай обсудим, как это исправить. В остальном код чистый и понятный.»
  • Плохо: «Этот код не работает. Всё плохо.»

3.2 Конкретика и примеры

Вместо «убери дублирование» напишите: «Этот блок повторяется в строках 45 и 78. Предлагаю вынести его в метод validateOrder().»

// Комментарий к ревью:
// ❌ "Плохой код"
// ✅ "Строка 23: использование '==' для сравнения строк может привести к ошибке. 
//    Замени на equals() или Objects.equals()."

3.3 Вопросы вместо утверждений

Вместо «это неправильно» спросите: «Почему ты выбрал именно этот подход?

Блоги

Рекомендаций по книгам