Говнокод — это сленговое название исходного кода низкого качества: нечитаемого, плохо структурированного и сложного в поддержке. По данным отчёта Stripe (2022), разработчики тратят до 40% рабочего времени на чтение и понимание плохо написанного кода. В русскоязычном сообществе термин настолько распространён, что существует специализированный сайт govnokod.ru, где разработчики публикуют примеры особенно ярких случаев.
Главное
Говнокод — это субъективная, но общепринятая характеристика кода, который не соответствует минимальным стандартам качества. Роберт Мартин в книге «Чистый код» (2008) определяет плохой код как код, который «мешает понять, что он делает». Говнокод может быть синтаксически корректным и даже работать, но его поддержка превращается в кошмар для команды.
Термин говнокод распространён именно в русскоязычном сообществе. В английском используются более формальные термины: spaghetti code, dirty code, technical debt code. Однако эмоциональная окраска «говнокода» точнее передаёт отношение разработчиков к такому коду — смесь раздражения, отвращения и профессиональной обиды.
По данным исследования McKinsey (2023), компании с высоким уровнем технического долга — а говнокод является его главной составляющей — тратят на 20–40% больше ресурсов на разработку новых функций. Качество кода напрямую влияет на бизнес-показатели, и это не метафора, а подтверждённый факт.
Объективных метрик не существует, но есть практические критерии: если разработчик тратит больше 5 минут на понимание функции из 20 строк — это говнокод. Если изменение одной строчки ломает три не связанных модуля — это говнокод. Если код невозможно покрыть тестами без полного переписывания — это говнокод.
Копипаста (copy-paste programming) — один из самых ярких и легко обнаруживаемых признаков. Когда один и тот же блок кода повторяется в нескольких местах с минимальными изменениями, это не просто говнокод, а источник будущих багов. Исправление в одном месте и пропуск в другом — типичная ситуация.
Бессмысленные имена переменных — классика. Переменные с именами `a`, `b`, `x`, `data`, `temp`, `tmp`, `result`, `list`, `obj` не несут никакой информации о своём назначении. Читатель кода вынужден анализировать всю функцию, чтобы понять, что хранится в переменной. Роберт Мартин называет это «ложью в имени» — имя обещает информацию, но не даёт её.
Глубокая вложенность — когда условия, циклы и обработка ошибок создают конструкцию с 5+ уровнями отступов. Такой код невозможно читать без боковой прокрутки или ментального отслеживания всех уровней. Это прямой путь к ошибкам: логические операторы легко перепутать, а закрывающие скобки — не заметить.
| Признак | Пример говнокода | Чистый код |
|---|---|---|
| Копипаста | Один блок скопирован 5 раз | Вынесен в функцию |
| Имена | `var a = getData()` | `var userList = getData()` |
| Вложенность | 6 уровней if/for | 2–3 уровня с return early |
| Функции | Функция на 300 строк | Разбита на 3–5 методов |
| Комментарии | `i++ // increment i` | Понятный код без комментариев |
Dead code — функции, переменные, классы, которые нигде не используются. Это увеличивает объём кода, отвлекает разработчика и создаёт ложное впечатление о возможностях системы. Magic numbers — числа без контекста. God-классы — классы, которые делают всё сразу, нарушая принцип единственной ответственности (SOLID: S).
Нехватка времени — наиболее частая причина. Когда дедлайны горят, разработчики жертвуют качеством в пользу скорости. Тактически это может быть оправдано, но стратегически — это накопление технического долга. Проблема в том, что «временный» говнокод редко возвращаются исправлять.
Отсутствие код-ревью — вторая по значимости причина. Когда код пишется в одиночку без проверки коллегами, плохие паттерны закрепляются и размножаются. Code review — это не просто контроль качества, но и передача знаний внутри команды. Проекты без ревью неизбежно скатываются в говнокод.
Низкая квалификация разработчика или отсутствие менторства. Junior-разработчики, оставленные без присмотра, естественным образом пишут говнокод — это часть процесса обучения. Проблема возникает, когда этот код попадает в продакшн без ревью и рефакторинга.
В командах, где «работает — и ладно» является девизом, говнокод процветает. Отсутствие стандартов кодирования, требований к тестированию и процессов ревью создаёт среду, в которой качество кода никого не волнует. Такие проекты быстро становятся «легаси» — кодом, который боятся трогать.
Основное последствие говнокода — замедление разработки. Парадокс плохого кода в том, что он позволяет быстро написать первую версию, но каждая последующая правка занимает всё больше времени. График зависимости скорости разработки от качества кода экспоненциальный — после определённого порога добавление новых функций становится практически невозможным.
Текучка кадров — косвенное, но серьёзное последствие. Разработчики, особенно опытные, не хотят работать с говнокодом. По данным Stack Overflow Developer Survey 2024, 47% разработчиков называют качество кодовой базы одним из ключевых факторов при выборе места работы. Проекты с плохим кодом теряют лучших сотрудников.
Безопасность — ещё одна жертва говнокода. Плохо написанный код содержит больше уязвимостей: необработанные исключения, SQL-инъекции, XSS, утечки памяти. Качественный код с unit-тестами и код-ревью отлавливает большинство таких проблем до продакшна.
SonarQube и аналогичные инструменты умеют оценивать технический долг в человеко-часах или днях. Например, 500 предупреждений о копипасте, 200 — о магических числах и 50 — о глубокой вложенности дают оценку в 30 дней технического долга. Эти цифры можно и нужно показывать менеджменту для обоснования рефакторинга.
Принцип DRY (Don't Repeat Yourself) — первое, что нужно внедрить. Каждый фрагмент логики должен существовать в единственном экземпляре. Вместо копипасты — вынесите повторяющийся код в отдельную функцию, класс или модуль. Вместо магических чисел — именованные константы. Вместо длинных функций — несколько маленьких.
Принцип KISS (Keep It Simple, Stupid) защищает от избыточной сложности. Если задачу можно решить в 10 строк — не надо писать 50. Если цикл проще стрима — используйте цикл. Если обычная функция понятнее декоратора — пишите функцию. Простота — главное качество поддерживаемого кода.
Принцип Boy Scout Rule — «оставь код лучше, чем ты его нашёл». Даже небольшие улучшения при каждой правке со временем превращают говнокод в приличный код. Переименовать переменную, разбить большую функцию, добавить тест — любое улучшение имеет значение.
// bad code — copy-paste, magic numbers, poor names
function calc(a, b, c) {
let x = a * 0.85;
if (b > 1000) { x = x * 0.9; }
let y = c * 0.85;
if (b > 1000) { y = y * 0.9; }
return x + y;
}
// clean code — clear names, DRY, constants
const DISCOUNT_RATE = 0.85;
const BULK_THRESHOLD = 1000;
const BULK_DISCOUNT = 0.9;
function applyDiscount(amount, quantity) {
let price = amount * DISCOUNT_RATE;
if (quantity > BULK_THRESHOLD) {
price = price * BULK_DISCOUNT;
}
return price;
}
function calculateTotal(items, quantity) {
return items.reduce((sum, item) => {
return sum + applyDiscount(item, quantity);
}, 0);
}
Рассмотрим типичный пример на Python. Функция обрабатывает заказы, но делает это плохо: 80 строк, глубокая вложенность, магические числа, дублирование. После рефакторинга код становится читаемым, тестируемым и сопровождаемым.
# bad code — single function does everything
def process_order(order):
if order.get("type") == "premium":
if order["amount"] > 100:
discount = 0.8
else:
discount = 0.9
else:
discount = 1.0
total = order["amount"] * discount
return total
# clean code — extracted functions and constants
class OrderProcessor:
PREMIUM_DISCOUNT_HIGH = 0.8
PREMIUM_DISCOUNT_LOW = 0.9
PREMIUM_THRESHOLD = 100
def get_discount(self, order):
if order.type == "premium" and order.amount > self.PREMIUM_THRESHOLD:
return self.PREMIUM_DISCOUNT_HIGH
return self.PREMIUM_DISCOUNT_LOW
def calculate_total(self, order):
return order.amount * self.get_discount(order)
Хорошая функция делает одну вещь и делает её хорошо. Если функция делает три разных действия — разбейте её. Если функция содержит более 20 строк — скорее всего, её можно разбить. Если в функции больше двух уровней отступов — нужен рефакторинг.
Статические анализаторы кода — первая линия обороны против говнокода. ESLint (JavaScript), Pylint (Python), SonarQube (мультиязычный), Checkstyle (Java) автоматически обнаруживают копипасту, магические числа, пустые catch-блоки, слишком длинные функции и сотни других антипаттернов.
Code style и форматтеры — второй уровень защиты. Prettier, Black, gofmt автоматически форматируют код, устраняя проблемы с пробелами, отступами и скобками. Единый стиль в команде делает код читаемым независимо от того, кто его писал. Споры о форматировании должны быть автоматизированы.
Код-ревью — третий и самый важный уровень. Ни один анализатор не заменит человека, который заметит, что архитектура решения неправильная, или что разработчик выбрал неверный подход. Эффективное ревью требует времени, но оно окупается снижением количества говнокода в разы.
Часто задаваемые вопросы
Крайне редко. В прототипировании или хакатонах скорость важнее качества, но такой код должен быть помечен как временный и не должен попадать в продакшн без рефакторинга. В продакшне оправданий говнокоду нет — любая экономия времени сейчас превратится в многократные потери в будущем.
Код новичка — это неопытный, но часто искренний код, который исправляется с ростом навыков. Говнокод — это сознательное или безразличное пренебрежение качеством. Новичок может написать неоптимальный, но читаемый код. Говнокод же нечитаем принципиально — его автору всё равно, поймут ли его другие.
Переписывание — крайняя мера. Постепенный рефакторинг безопаснее: вы выделяете модуль, покрываете его тестами, переписываете часть за частью. Полное переписывание risky — вы можете потерять бизнес-логику, накопленную в старом коде, включая обработку edge cases, которые никто не документировал.
Используйте метрики: SonarQube покажет технический долг в часах. Покажите, сколько времени тратится на баги в старом коде. Сравните скорость разработки новой функциональности в «чистой» и «грязной» частях проекта. Переведите на язык бизнеса: время — это деньги, а говнокод стоит денег.
«Чистый код» Роберта Мартина (2008) — библия качественного программирования. В ней описаны принципы именования, форматирования, обработки ошибок и тестирования. Дополнительно: «Совершенный код» Стива Макконнелла, «Рефакторинг» Мартина Фаулера, «Банды четырёх» про паттерны проектирования. Эти книги должен прочитать каждый разработчик.
Итоги
Мы разработаем мобильное приложение под ключ
IT Sectr создаёт приложения для iOS и Android для стартапов и бизнеса с 2017 года. Мы проконсультируем вас и предложим наилучшее решение.
Читайте также