Code smell, или запах кода, это признак того, что код работает, но его трудно читать и менять. Баг ломает поведение, а запах только усложняет жизнь тому, кто откроет файл завтра. Ниже разберем шесть классических запахов с короткими примерами до и пос…
400 000+ органических переходов за 3 месяца. Со-основатель GoBanana (231K пользователей, 12+ млн ₽ без рекламы) и NeuroScribe (65K пользователей). SEO/GEO-стратегии для AI-поисковиков, 1 700+ единиц контента, 17+ реализованных стратегий.
Об авторе →Claude Code: новый CLI-агент от Anthropic
Anthropic выпустила Claude Code — терминальный AI-агент для разработчиков. Инструмент работает прямо в командной строке и умеет писать, редактировать и запускать код.
Zcode AI: Полный гид по визуальному интерфейсу для Claude Code и AI-агентов
Узнайте, как использовать Zcode для управления Claude Code, Gemini и Codex в едином GUI. Настройка провайдеров, MCP-серверов и визуальный вайбкодинг.
YouTube-канал с монетизацией из любой точки мира: Пошаговый гайд 2026
Инструкция по созданию YouTube-канала: обход блокировок SMS, настройка расширенных функций через виртуальные номера и правила безопасности для монетизации.
Windsurf Code Maps: Как глубоко понимать архитектуру проекта перед написанием кода
Полный гайд по Windsurf Code Maps, модели Sway 1.5 и Sway Grep. Узнайте, как визуализировать архитектуру кода и ускорить разработку в 13 раз.
Vk Fast Cash Strategy
Аудитория ВКонтакте — это те же люди, что и в Instagram, но 'социальный контракт' площадки другой. Если Instagram — это 'дорогой ресторан' с демонстрацией успеха, то VK — это 'душевная шашлычная'. Здесь не работает глянцевый 'успешный успех
Code smell, или запах кода, это признак того, что код работает, но его трудно читать и менять. Баг ломает поведение, а запах только усложняет жизнь тому, кто откроет файл завтра. Ниже разберем шесть классических запахов с короткими примерами до и после, покажем, как их ловит SonarQube, и честно скажем, когда чинить не нужно.
TL;DR: Запах кода не ломает программу, но повышает цену каждой правки. Шесть запахов встречаются чаще всего: длинный метод, дубли, магические числа, божественный класс, длинный список параметров и зависть к чужим данным. SonarQube относит такие замечания к maintainability. Чинить стоит выборочно и только с тестами.
Code smell это участок кода, который работает, но написан так, что его сложно понимать и менять. Запах указывает на возможную проблему в структуре, а не на ошибку в поведении.
Code smell это симптом плохой структуры: программа отвечает правильно, а разобраться, почему, непросто. Термин закрепился благодаря Кенту Беку и Мартину Фаулеру и их книге о рефакторинге, подробнее в заметке Фаулера о code smell.

Представьте кухню, где ножи лежат вперемешку с батарейками. Готовить можно. Но каждый раз вы тратите лишние две минуты на поиск, и однажды схватите не то. С кодом то же самое, только «лишние две минуты» умножаются на всех, кто в нем работает.
Важная деталь: запах это повод присмотреться, а не приговор. Иногда длинная функция оправдана. Опытный разработчик чувствует запах, но решает по ситуации.
Баг меняет поведение программы и дает неверный результат. Запах кода поведение не трогает, он делает код запутанным и дорогим в поддержке.

Разница в том, что видит пользователь. Баг он заметит: кнопка не нажимается, сумма посчиталась неверно. Запах пользователь не увидит никогда, его почувствует только разработчик, когда на простую правку уйдет полдня.
В документации SonarQube для таких замечаний есть отдельный тип: maintainability issue, то есть замечание о поддерживаемости. Там прямо сказано, что это проблема, из-за которой код запутан и его сложно поддерживать, подробности в разделе про issues.
| Признак | Баг | Code smell |
|---|---|---|
| Поведение программы | Неверное | Верное |
| Кто замечает | Пользователь, тесты | Разработчик на ревью |
| Цена | Сбой прямо сейчас | Замедление правок потом |
| Срочность | Обычно высокая | Обычно средняя или низкая |
Шесть классических запахов: длинный метод, дублирование, магические числа, божественный класс, длинный список параметров и зависть к чужим данным. У каждого есть простое лечение.
Ниже по каждому запаху три вещи: как выглядит, чем вредит, как исправить. Примеры на JavaScript, но логика одинакова в любом языке.
Функция делает сразу проверку, расчет, скидку и отправку письма. Читать ее приходится сверху донизу, а менять одну часть страшно, потому что все связано.
// до
function processOrder(order) {
if (!order.items.length) throw new Error("empty");
let total = 0;
for (const i of order.items) total += i.price * i.qty;
if (order.user.vip) total *= 0.9;
sendEmail(order.user.email, "Заказ на сумму " + total);
return total;
}
// после
function processOrder(order) {
validate(order);
const total = applyDiscount(calcTotal(order.items), order.user);
notify(order.user, total);
return total;
}Лечение: выделить каждый шаг в функцию с говорящим именем. Теперь processOrder читается как оглавление.
Один и тот же кусок скопирован в двух местах. Нашли ошибку в одном, забыли про второй, и вот вы уже правите баг дважды.
// до
const userPrice = "$" + (p / 100).toFixed(2);
const adminPrice = "$" + (p / 100).toFixed(2);
// после
const formatPrice = (p) => "$" + (p / 100).toFixed(2);Лечение: вынести повторяющееся в одну функцию. Правило простое: увидели одно и то же в третий раз, пора выносить.
Число без объяснения. Через месяц никто не вспомнит, что такое 1.2 и почему именно 86400.
// до
const gross = price * 1.2;
const expires = Date.now() + days * 86400 * 1000;
// после
const VAT_RATE = 1.2;
const MS_IN_DAY = 24 * 60 * 60 * 1000;
const gross = price * VAT_RATE;
const expires = Date.now() + days * MS_IN_DAY;Лечение: дать числу имя константы. Заодно смена ставки НДС превращается в правку одной строки.
Один класс знает все: логин, письма, отчеты, сохранение в базу. Его боятся трогать, и в нем постоянно конфликтуют правки разных людей.
// до
class UserManager {
login() {}
sendEmail() {}
buildReport() {}
saveToDb() {}
}
// после
class AuthService {}
class Mailer {}
class ReportBuilder {}
class UserRepository {}Лечение: разрезать по ответственности. У каждого класса одна причина меняться.
Функция принимает восемь аргументов, и на вызове легко перепутать порядок.
// до
createUser("Аня", "a@mail.ru", "+7900", "Москва", "Тверская", "125009", false, true);
// после
createUser({
name: "Аня",
email: "a@mail.ru",
phone: "+7900",
address: { city: "Москва", street: "Тверская", zip: "125009" },
isAdmin: false,
subscribed: true,
});Лечение: передавать объект. Порядок больше не важен, а вызов читается сам.
Метод одного класса постоянно лезет в поля другого, вместо того чтобы попросить его сделать работу. По-английски feature envy.
// до
class Invoice {
address() {
const a = this.customer.address;
return a.city + ", " + a.street + ", " + a.zip;
}
}
// после
class Customer {
fullAddress() {
const a = this.address;
return a.city + ", " + a.street + ", " + a.zip;
}
}Лечение: перенести логику туда, где живут данные. Invoice просто вызывает customer.fullAddress().

SonarQube относит такие замечания к maintainability и учитывает их в оценке технического долга. В новых версиях акцент смещен на качества ПО и атрибуты Clean Code, но термин остался в документации.
Анализатор читает исходники без запуска и применяет наборы правил: слишком сложная функция, дубли блоков, неиспользуемые переменные. Каждое срабатывание попадает в отчет с оценкой того, сколько времени уйдет на исправление. Из этих оценок складывается технический долг проекта.
Стоит знать, что подход менялся. Раньше SonarQube делил замечания на баги, уязвимости и code smells. В новых версиях основной упор на три качества: security, reliability и maintainability, а также на атрибуты Clean Code. Как это устроено, описано в документации про Clean Code. Если вы работаете с версией новее или старше, названия в интерфейсе могут отличаться.
Практика такая: подключили анализ в CI, посмотрели на самые частые правила и выбрали два-три, которые бьют по вам сильнее всего.

Найти запахи можно глазами на ревью, линтером, инспекциями IDE или анализатором вроде SonarQube. Лучше всего работает комбинация: автоматика ловит очевидное, человек оценивает смысл.
Автоматика хороша в подсчете: длина функции, вложенность, дубли. Человек хорош в смысле: почему этот класс разросся и что с ним делать. Поэтому связка сильнее любого из вариантов по отдельности.
| Способ | Что ловит | Слабое место |
|---|---|---|
| Ревью глазами | Смысловые запахи, god class, feature envy | Зависит от опыта и внимания |
| Линтер (например, ESLint) | Сложность, неиспользуемый код, стиль | Мало видит на уровне архитектуры |
| Инспекции IDE | Дубли и упрощения прямо при написании | Правила по умолчанию не подходят всем |
| SonarQube | Maintainability по всему репозиторию, тренд долга | Настройка, шум от неточных правил |
Если вы пишете код в Cursor или Claude Code, попросите агента отдельным шагом провести ревью на запахи после того, как код заработал. Это дешево и заметно чистит результат.
AI-агент легко копирует похожие блоки, поэтому дублирование в его коде стоит проверять первым. Надежной статистики по рынку у нас нет, поэтому мы ее не приводим.
Агент решает задачу, которую вы поставили, и обычно не смотрит на весь репозиторий. Просите «добавь такую же форму для админов», и он с радостью скопирует прежнюю целиком. Работает, тесты зеленые, а дубль уже в проекте.
Кстати, для новичков в вайбкодинге это самая частая ловушка. Код запустился, значит, все хорошо. На практике через пару недель правка одной кнопки превращается в охоту по пяти файлам.
Максим: «Мог просто засесть до пяти ночи и править одну какую-то функцию, которая не работала. В моменте я уже испотел, и мне хотелось все закрыть. Но я понимал, что это можно решить и нужно решить, чтобы идти дальше.»
Чистый код экономит именно такие ночи. Чем проще структура, тем короче путь до нужной функции, особенно когда вы правите проект вместе с агентом.

Не каждый запах надо чинить сразу. Автоматические правила бывают неточны, а рефакторинг без тестов опасен: можно сломать то, что работало.
Честно о слабых сторонах подхода. Правила анализаторов срабатывают на код, который в контексте нормален: длинная функция с простой линейной логикой может читаться лучше, чем десять мелких. Шум в отчете быстро отбивает охоту им пользоваться.
Второе ограничение серьезнее. Рефакторинг меняет структуру, а значит, без тестов вы не узнаете, что поведение осталось прежним. Сначала тесты, потом чистка. Не наоборот.
Что помогает на практике:

Начните с трех вещей: найдите дубли, разбейте самую длинную функцию и замените магические числа константами. Этого хватает, чтобы заметить эффект за один вечер.
Возьмите свой самый часто меняемый файл. Посмотрите, что в нем длиннее экрана, что скопировано и что непонятно без комментария. Исправьте одно, запустите тесты, закоммитьте. Так вы прокачаете чутье на запахи быстрее, чем от любой теории.
Если хотите разобрать свой проект на живом примере, запишитесь на консультацию к Максиму. А подобрать инструмент, который поможет с ревью кода, можно в каталоге AI-инструментов.

Это место в коде, которое работает, но написано так, что его трудно читать и менять. Как беспорядок в комнате: жить можно, но нужную вещь ищешь долго. Сам по себе запах ничего не ломает, он повышает цену каждой следующей правки.
Нет. Баг меняет поведение программы и дает неверный результат. Запах поведение не меняет, он делает код запутанным. Программа с запахами может годами работать без сбоев, но развивать ее будет дорого и неприятно.
Два пути. Первый: ревью глазами по списку классических запахов. Второй: анализатор вроде SonarQube или линтер, который подсвечивает длинные функции и дубли. Лучше всего работают оба вместе.
Нет. Чините запахи там, где вы и так меняете код или где они мешают каждый день. Массовый рефакторинг без тестов рискованнее самих запахов. Начните с файлов, которые правятся чаще всего.
В документации SonarQube такие замечания относятся к maintainability, то есть к поддерживаемости кода, и учитываются в оценке технического долга. В новых версиях акцент сместился на качества ПО и атрибуты Clean Code, но термин остался.
Агент легко копирует похожие блоки, поэтому дубли в его коде проверяйте в первую очередь. Точных цифр по рынку мы не приводим, потому что надежного источника нет. Проверьте свой репозиторий сами, это займет полчаса.
Code smell (запах кода) - признак структурной проблемы в коде, который работает, но трудно читается и меняется.
Рефакторинг - изменение структуры кода без изменения его поведения.
Maintainability (поддерживаемость) - насколько легко код читать, менять и расширять.
Технический долг - накопленная цена будущих исправлений из-за неидеальной структуры кода.
Статический анализ - проверка исходников без запуска программы, по набору правил.
Feature envy (зависть к чужим данным) - метод, который в основном работает с данными чужого класса.
God class (божественный класс) - класс, который берет на себя слишком много обязанностей.
Линтер - инструмент, который находит ошибки стиля и подозрительные конструкции в коде.
Обновлено: сентябрь 2026