Опишите распространённые анти‑паттерны (God object, Spaghetti code, Cargo cult programming), как их распознавать в проекте и конкретные шаги по их устранению в кодовой базе
God object - Что это: один класс/модуль аккумулирует слишком много ответственности (данные + логика + управление), нарушая SRP. - Как распознать: - Класс с очень большим размером (метрикa: файл > 500500500 строк или >>>505050 методов). - Много внешних зависимостей и ветвлений внутри одного места. - Частые правки в одном файле при разных задачах (history churn). - Низкая модульность — тесты тяжело писать из‑за множества побочных эффектов. - Конкретные шаги по устранению: 1. 111 — Написать модульные тесты вокруг текущего поведения (фиксация контрактов). 2. 222 — Применить «Extract Class» / «Extract Module»: выделять связанные поля и методы в новые классы (маленькими шагами, сохранять тесты). 3. 333 — Ввести интерфейсы/абстракции и реализовать зависимость через DI, чтобы уменьшить связность. 4. 444 — Перенести данные и операции ближе к тому месту, которому они логически принадлежат (пересмотреть границы ответственности). 5. 555 — Добавить линтеры/метрики (например, максимальная длина класса) и правило code review, чтобы не допускать повторного роста. 6. 666 — Рефакторить инкрементально на ветках, постоянно прогоняя тесты. Spaghetti code - Что это: запутанный поток управления и сильная сцепка — длинные функции, goto‑подобные ветвления, смешивание уровней абстракции. - Как распознать: - Функции слишком длинные (порог: > 505050 строк) и высокая цикломатическая сложность (цC > 101010). - Большое количество вложенных условных и цикловых конструкций. - Трудно читать и понимать поток данных; изменения рождают регрессии в непредсказуемых местах. - Низкое покрытие тестами и частые «fixes» в разных частях кода за одну задачу. - Конкретные шаги по устранению: 1. 111 — Измерить метрики (cyclomatic complexity, function length, coupling) с помощью инструментов (ESLint/TSLint, pylint, SonarQube, CodeClimate). 2. 222 — Применять «Extract Method» и «Introduce Parameter/Object»: разбить большие функции на маленькие с понятными именами. 3. 333 — Выделить уровни абстракции и слои (presentation, domain, persistence) и ограничить зависимости между ними. 4. 444 — Ввести явные границы побочных эффектов (side‑effect free core, I/O в отдельных модулях). 5. 555 — Покрыть код автоматическими тестами перед и после рефакторинга, рефакторить безопасно по маленьким шагам. 6. 666 — Настроить CI с проверками метрик и обязать рефактор‑PR иметь небольшие и понятные изменения. Cargo cult programming - Что это: копирование шаблонных фрагментов, паттернов или внешних решений «потому что так делают», без понимания зачем. - Как распознать: - В коде много скопированных блоков с комментариями «TODO: разобраться» или без изменений. - Использование библиотек/паттернов без тестов и без явной нужды. - Магические константы и сложные конструкции, объяснение которых отсутствует в коде/PR. - Комментарии типа «copied from X» или большое количество кода, который никто не понимает. - Конкретные шаги по устранению: 1. 111 — Провести аудит зависимостей и мест с подозрительным кодом; пометить участки для ревью/объяснения. 2. 222 — Требовать в PR объяснения «почему» (motivation) для любого нетривиального куска кода; если объяснение отсутствует — отклонять или требовать упрощения. 3. 333 — Удалять ненужный или неиспользуемый код и библиотеки (tree shaking, статический анализ), заменяя копипаст тестами или простыми решениями. 4. 444 — Документировать сложные решения: архитектурные решения, обязательные шаблоны, примеры использования и ограничения. 5. 555 — Внедрить культуру знаний: парное программирование, обзоры архитектуры, внутренние обучающие сессии. 6. 666 — Добавить автоматические проверки (lint rules, запрет на «any»/unsafe конструкции) и шаблоны PR с полем «why»/«alternatives considered». Инструменты и практики, которые помогают для всех трёх: - Метрики: cyclomatic complexity, LOC, coupling, code churn (пороговые значения устанавливать командно). - Инструменты: SonarQube, CodeClimate, ESLint/pylint, static analyzers, IDE‑рефакторинг. - Практики: тесты до рефакторинга, маленькие инкрементальные PR, обязательные code reviews, документирование решений и обучение команды.
- Что это: один класс/модуль аккумулирует слишком много ответственности (данные + логика + управление), нарушая SRP.
- Как распознать:
- Класс с очень большим размером (метрикa: файл > 500500500 строк или >>> 505050 методов).
- Много внешних зависимостей и ветвлений внутри одного места.
- Частые правки в одном файле при разных задачах (history churn).
- Низкая модульность — тесты тяжело писать из‑за множества побочных эффектов.
- Конкретные шаги по устранению:
1. 111 — Написать модульные тесты вокруг текущего поведения (фиксация контрактов).
2. 222 — Применить «Extract Class» / «Extract Module»: выделять связанные поля и методы в новые классы (маленькими шагами, сохранять тесты).
3. 333 — Ввести интерфейсы/абстракции и реализовать зависимость через DI, чтобы уменьшить связность.
4. 444 — Перенести данные и операции ближе к тому месту, которому они логически принадлежат (пересмотреть границы ответственности).
5. 555 — Добавить линтеры/метрики (например, максимальная длина класса) и правило code review, чтобы не допускать повторного роста.
6. 666 — Рефакторить инкрементально на ветках, постоянно прогоняя тесты.
Spaghetti code
- Что это: запутанный поток управления и сильная сцепка — длинные функции, goto‑подобные ветвления, смешивание уровней абстракции.
- Как распознать:
- Функции слишком длинные (порог: > 505050 строк) и высокая цикломатическая сложность (цC > 101010).
- Большое количество вложенных условных и цикловых конструкций.
- Трудно читать и понимать поток данных; изменения рождают регрессии в непредсказуемых местах.
- Низкое покрытие тестами и частые «fixes» в разных частях кода за одну задачу.
- Конкретные шаги по устранению:
1. 111 — Измерить метрики (cyclomatic complexity, function length, coupling) с помощью инструментов (ESLint/TSLint, pylint, SonarQube, CodeClimate).
2. 222 — Применять «Extract Method» и «Introduce Parameter/Object»: разбить большие функции на маленькие с понятными именами.
3. 333 — Выделить уровни абстракции и слои (presentation, domain, persistence) и ограничить зависимости между ними.
4. 444 — Ввести явные границы побочных эффектов (side‑effect free core, I/O в отдельных модулях).
5. 555 — Покрыть код автоматическими тестами перед и после рефакторинга, рефакторить безопасно по маленьким шагам.
6. 666 — Настроить CI с проверками метрик и обязать рефактор‑PR иметь небольшие и понятные изменения.
Cargo cult programming
- Что это: копирование шаблонных фрагментов, паттернов или внешних решений «потому что так делают», без понимания зачем.
- Как распознать:
- В коде много скопированных блоков с комментариями «TODO: разобраться» или без изменений.
- Использование библиотек/паттернов без тестов и без явной нужды.
- Магические константы и сложные конструкции, объяснение которых отсутствует в коде/PR.
- Комментарии типа «copied from X» или большое количество кода, который никто не понимает.
- Конкретные шаги по устранению:
1. 111 — Провести аудит зависимостей и мест с подозрительным кодом; пометить участки для ревью/объяснения.
2. 222 — Требовать в PR объяснения «почему» (motivation) для любого нетривиального куска кода; если объяснение отсутствует — отклонять или требовать упрощения.
3. 333 — Удалять ненужный или неиспользуемый код и библиотеки (tree shaking, статический анализ), заменяя копипаст тестами или простыми решениями.
4. 444 — Документировать сложные решения: архитектурные решения, обязательные шаблоны, примеры использования и ограничения.
5. 555 — Внедрить культуру знаний: парное программирование, обзоры архитектуры, внутренние обучающие сессии.
6. 666 — Добавить автоматические проверки (lint rules, запрет на «any»/unsafe конструкции) и шаблоны PR с полем «why»/«alternatives considered».
Инструменты и практики, которые помогают для всех трёх:
- Метрики: cyclomatic complexity, LOC, coupling, code churn (пороговые значения устанавливать командно).
- Инструменты: SonarQube, CodeClimate, ESLint/pylint, static analyzers, IDE‑рефакторинг.
- Практики: тесты до рефакторинга, маленькие инкрементальные PR, обязательные code reviews, документирование решений и обучение команды.