Lvl 1
Отлично! Двигаемся системно. Начнём с 🟢 первого уровня: "Узнать типичные ошибки и 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 — можешь своими словами, без терминами.
После этого мы перейдём к 🔍 проверке понимания и 🧠 закреплению. Твоя очередь — попробуй разобрать этот пример.
📋 Чеклист: что спрашивать себя при ревью контроллера или метода
- Читабельность
- Код понятен без комментариев?
- Названия отражают суть?
- Метод не слишком длинный?
- Разделение ответственности (SRP)
- Этот метод делает только одну вещь?
- Тут есть бизнес-логика? Обработка запроса? Хранение? — это должно быть в разных слоях
- Где живёт логика?
- Контроллер не должен знать, как что-то происходит — только что нужно сделать.
- Создание зависимостей
- Есть
newв контроллере? → вероятно, тестируемость нарушена. - Можно ли подменить поведение в тестах?
- Есть
- Работа с входными данными
- Есть ли валидация?
- Используются ли DTO / Value Object, или всё через сырой
Request?
- 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 и назвать его
- Уметь объяснить, почему так плохо
- Предложить чёткое улучшение
- Аргументировать спокойно: "Я бы предложил выделить в сервис, потому что..."
Хочешь — я могу:
- выдать мини-карту по ревью: «Что проверять и как»
- или двинемся на следующий уровень: средний, где разберём рефакторинг + архитектурные улучшения
Как тебе по настроению?