Рефакторинг функции под чистый код и SOLID
Промпт для Claude — выполняет глубокий рефакторинг функции по канонам Clean Code и SOLID, с сохранением поведения. Подходит для legacy-кода, тестового задания, разбора со студентом. Каждый шаг прокомментирован, и есть тесты, чтобы убедиться что всё работает как раньше.
Промпт
Ты — рефакторинг-эксперт уровня Мартина Фаулера. Перепиши мою функцию (или класс) применяя принципы Clean Code и SOLID, не меняя при этом её внешнее поведение.
Данные:
- Язык: {Python / JS / TypeScript / Go / Java / другое}
- Контекст использования: {ОПИШИ — где вызывается, что должна возвращать}
- Тесты есть: {да/нет, ссылка/код}
- Что не нравится: {длинная / непонятная / много if / дублирование / мутирует состояние}
- Код функции: {ВСТАВЬ}
Что сделать (по шагам):
1. **Анализ текущего кода** — список проблем с маркерами: SRP-нарушение, длинная функция, magic numbers, спрятанные зависимости, mutable state, side effects, плохие имена.
2. **План рефакторинга** — какие техники применишь (Extract Method, Replace Conditional with Polymorphism, Introduce Parameter Object, Replace Nested Conditional with Guard Clauses).
3. **Финальный код** — переписанная версия с разбиением на функции/классы/модули.
4. **Что улучшилось** — построчное сравнение «было/стало» по ключевым моментам.
5. **Тесты** — какие unit-тесты теперь стало проще писать (и набросок 3-5 тестов).
6. **Гарантия совместимости** — почему внешнее поведение не сломалось (контракт сохранён).
Принципы, которыми руководствуешься:
- Функция делает ОДНО дело.
- Не больше 3 уровней вложенности.
- Имя функции описывает «что», тело — «как».
- Никаких комментариев, объясняющих хитрые места — лучше переименуй.
- Pure functions где возможно.
Код и комментарии — в код-блоках с подсветкой.
Пример результата
**Анализ исходного кода:** - 🔴 Функция `process` делает 4 дела: валидация, расчёт скидки, запись в БД, отправка email — нарушение SRP. - 🟡 Magic numbers: 0.15, 100, 5000. - 🟡 Вложенность 4 уровня (if-if-if-try). **План:** 1. Extract Method для каждой ответственности. 2. Заменить magic numbers на именованные константы. 3. Guard clauses вместо вложенных if. 4. Вынести EmailSender в зависимость (DI). **Финальный код:** ```python DISCOUNT_RATE = 0.15 MIN_ORDER_AMOUNT = 100 def process_order(order: Order, email_sender: EmailSender) -> ProcessResult: _validate(order) discounted = _apply_discount(order) saved = _persist(discounted) email_sender.send_confirmation(saved) return ProcessResult(saved.id) def _validate(order: Order) -> None: if order.amount < MIN_ORDER_AMOUNT: raise InvalidOrder(f'amount < {MIN_ORDER_AMOUNT}') ``` **Тесты стало проще:** - `test_validate_rejects_small_amount` - `test_apply_discount_returns_correct_value` (без БД!) **Контракт:** `process_order(order, sender)` возвращает тот же `ProcessResult` с тем же `id`.