Отлично! Двигаемся системно. Начнём с 🟢 первого уровня: "Узнать типичные ошибки и smell'ы" в PHP-коде, в рамках подготовки к code review.

🧩 🟢 Уровень 1: Code Review — типичные ошибки и smell’ы

💡 1. Концепция: зачем вообще смотреть на smell’ы

Smell (запах кода) — это признак потенциальной проблемы в коде, которая ещё не баг, но:

  • усложняет чтение и поддержку
  • мешает повторному использованию
  • ухудшает тестируемость
  • может превратиться в баг или боль в будущем

⛔ Smell'ы — это не про "неправильно", это про "неустойчиво", "хрупко", "грязно".

📌 Примеры smell'ов, которые важно уметь распознавать:

одинаковые конструкции копипастятся по методам
делает слишком много, SRP нарушен
контроллер сам хеширует, валидирует, шлёт письма
непонятные конструкции ради "ускорения"
объекты напрямую создают/используют друг друга
вложенные блоки управления (вместо паттернов)
внешний код обращается к свойствам напрямую

Пример
Дублирование кода
Большой метод / класс
Нарушение SRP / логика в контроллере
Магические строки/числа 'admin', 'user', 7, 86400 — без констант
Логика в шаблонах или вьюхах if ($user->isAdmin()) { ... } в шаблоне
Флаги в параметрах методов doSomething($hardMode = false)
Преждевременная оптимизация
Плотная связность
Много if/else/elseif
Нарушение инкапсуляции
Дублирование условий if ($user && $user->isActive() && $user->isVerified()) — в 10 местах

⚒️ 2. Применение: мини-задача

Вот кусок кода — попробуй распознать хотя бы 3 smell’а:

class InvoiceController {    public function generate(Request $request)    {        $invoice = new Invoice();        $invoice->date = date('Y-m-d');        $invoice->amount = $request->get('amount');        $invoice->type = $request->get('type');        $invoice->status = 'unpaid';         if ($invoice->type === 'urgent') {            $invoice->priority = 1;        } else {            $invoice->priority = 5;        }         $invoice->save();         Logger::log('Invoice created: ' . json_encode($invoice));         return json_encode(['success' => true]);    } } 

🧠 Вопрос: какие проблемы ты тут видишь?
Назови хотя бы 3 — можешь своими словами, без терминами.

После этого мы перейдём к 🔍 проверке понимания и 🧠 закреплению. Твоя очередь — попробуй разобрать этот пример.


📋 Чеклист: что спрашивать себя при ревью контроллера или метода

  1. Читабельность
    • Код понятен без комментариев?
    • Названия отражают суть?
    • Метод не слишком длинный?
  2. Разделение ответственности (SRP)
    • Этот метод делает только одну вещь?
    • Тут есть бизнес-логика? Обработка запроса? Хранение? — это должно быть в разных слоях
  3. Где живёт логика?
    • Контроллер не должен знать, как что-то происходит — только что нужно сделать.
  4. Создание зависимостей
    • Есть new в контроллере? → вероятно, тестируемость нарушена.
    • Можно ли подменить поведение в тестах?
  5. Работа с входными данными
    • Есть ли валидация?
    • Используются ли DTO / Value Object, или всё через сырой Request?
  6. Side effects / I/O
    • Кто вызывает save()? mail()? log()? — всё это побочные эффекты → лучше делегировать


Если ты можешь сказать:

"В реальной жизни это правило должно соблюдаться" — это бизнес-логика.

Бизнес-логика — это набор правил, условий и действий, которые отражают реальную логику работы системы с точки зрения продукта или бизнеса.



🔥 Да, ты реально круто прошёл эту тему. Не просто прочитал, а вник, разобрался и начал думать как архитектор — это уже уровень выше просто "сделать по ТЗ".

Давай подведу короткое резюме, чтобы ты мог легко освежить в голове перед собеседованием:

✅ Code Review — типичные ошибки и smell’ы: что нужно знать

💡 Концепции:

  • Code Review = не только поиск багов, но оценка читаемости, архитектуры, ответственности
  • Smell = признак слабого места: ещё не баг, но потенциальная боль

🧨 Основные smell’ы:

  • ❌ Логика в контроллере (нарушение SRP)
  • ❌ new внутри метода (жесткая связность)
  • ❌ Прямая работа с Request (сырой ввод без структуры)
  • ❌ Магические строки / числа
  • ❌ Нарушение инкапсуляции (свойства публичные без нужды)
  • ❌ Логгер / mail / DB вызываются напрямую
  • ❌ Сложные if/else, вложенность, дублирование
  • ❌ Нарушение слоя ответственности (контроллер делает всё сам)

✅ Как надо:

  • Использовать DTO для чистых и проверенных входных данных
  • Делегировать всю логику в сервисы / фабрики / репозитории
  • Внедрять зависимости через конструктор (DI)
  • Использовать интерфейсы для гибкости и тестируемости
  • Писать мелкие, предсказуемые методы по принципу SRP
  • Избегать жёстких связей, чтобы легко тестировать и расширять

🎯 На собесе:

  • Уметь увидеть smell и назвать его
  • Уметь объяснить, почему так плохо
  • Предложить чёткое улучшение
  • Аргументировать спокойно: "Я бы предложил выделить в сервис, потому что..."

Хочешь — я могу:

  • выдать мини-карту по ревью: «Что проверять и как»
  • или двинемся на следующий уровень: средний, где разберём рефакторинг + архитектурные улучшения

Как тебе по настроению?