Мы все сталкивались с этим: открываешь репозиторий, а там код, который вроде бы работает, но при ближайшем рассмотрении вызывает лёгкую дрожь в руках. В этой статье я хочу поговорить о том, как «студенческий» код, написанный в спешке или ради эксперимента, неожиданно становится частью продакшн-систем. Разберём примеры, посмотрим, как такие артефакты выживают, какие последствия это несёт, и что с этим можно сделать, чтобы не жить на пороховой бочке.

картинка сгенерирована ии :)
картинка сгенерирована ии :)

Код как наследие, а не как артефакт

Давайте честно: почти каждый из нас когда-то писал код «на коленке», чтобы лишь бы заработало. Никакой архитектуры, никакого CI/CD, максимум пара костылей и комментарий «TODO: потом переписать». Прошло пять лет, проект вырос, деньги пошли, а ваш старый скрипт — часть критической бизнес-логики. Знакомо?

Интересно то, что подобный код — это не просто мусор, а настоящее наследие. Оно похоже на старую проводку в доме: пока всё работает — никто не трогает. Но стоит начать реконструкцию, и внезапно выясняется, что «фаза» идёт через кухню на гараж, а гаража уже нет.

Я заметил, что многие команды воспринимают «старый код» как врага. А зря: это скорее зеркало нашей инженерной молодости, из которого можно вытащить ценные уроки. Впрочем, иногда лучше не смотреть — чтобы не травмироваться.


Когда прототип становится «боевой системой»

Самый яркий пример — когда скрипт для лабораторной по базам данных становится частью платежной системы. Звучит абсурдно? Но давайте посмотрим код на Python, который я встретил в одном проекте (названия переменных и деталей изменены, но суть сохранена):

# payment_processor.py
import sqlite3
import time

def process_payment(user_id, amount):
    conn = sqlite3.connect("payments.db")
    cursor = conn.cursor()
    cursor.execute("INSERT INTO transactions(user_id, amount, ts) VALUES (?, ?, ?)", 
                   (user_id, amount, int(time.time())))
    conn.commit()
    conn.close()
    return True

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

Именно так из прототипов вырастают «боевые» системы: никто не планировал, никто не проектировал, просто никто не нашёл времени переписать. И это куда более массовое явление, чем кажется.


Код как археологический артефакт

Читали когда-нибудь чужой код и ловили ощущение, будто раскапываете древние руины? Иногда попадаются комментарии вроде:

// Хак, чтобы работало с IE6. Не трогать, иначе всё упадёт.
function calcOffset(el) {
    return el.offsetTop + el.offsetParent.offsetTop; // TODO: проверить
}

В такие моменты хочется спросить: «А зачем это всё ещё работает?» Но тут кроется одна важная мысль: код — это исторический слой. Как годовые кольца на дереве. По комментариям и странным решениям можно отследить эволюцию технологий.

И вот парадокс: чем хуже был написан код, тем дольше он может прожить. Почему? Потому что все боятся его трогать. Разработчики называют это «legacy freeze»: система работает, тестов нет, документации нет, тронешь — упадёт. Значит, лучше пусть живёт как есть.


Системная цена «студенческого кода»

В один момент наступает пора платить по счетам. И тут становится ясно: каждая строчка кода имеет стоимость. Только стоимость эта не в момент написания, а спустя годы.

Рассмотрим пример на Java:

public class ConfigLoader {
    public String getConfig(String key) {
        try {
            Properties props = new Properties();
            FileInputStream in = new FileInputStream("config.txt");
            props.load(in);
            in.close();
            return props.getProperty(key);
        } catch (Exception e) {
            return null; // ну и ладно
        }
    }
}

Поначалу это выглядит безобидно: «мелкая утилитка». Но через годы весь сервис начинает зависеть от config.txt. Хочешь перенести в Kubernetes — сюрприз, придётся городить костыли.

Так формируется технический долг, который в какой-то момент обгоняет финансовый. А расплачиваться приходится не только временем разработчиков, но и реальными деньгами бизнеса, потому что старый код тормозит внедрение новых фич.


Что с этим делать и как не сойти с ума

И вот главный вопрос: что делать, если твоя система на 40% состоит из кода «цифрового детства»?

Во-первых, принять, что это нормально. В любой живой инфраструктуре всегда есть тёмные углы. Во-вторых, важно не пытаться всё переписать сразу. Я видел команды, которые бросались в «тотальный рефакторинг», и через полгода проект закрывался, потому что бизнес устал ждать.

Лучше идти постепенно:

  • выделять модули-кандидаты для переписывания;

  • писать тесты для самого страшного кода (пусть даже поверхностные);

  • фиксировать архитектурные решения хотя бы в виде README;

  • и самое важное — обсуждать с командой: что мы готовы «заморозить», а что надо трогать.

Я, например, люблю подход «археологии кода»: раз в квартал устраивать разбор «наследия», вытаскивать старые куски и обсуждать их с новичками. Это и весело, и полезно: учишь команду критически смотреть на код, а заодно документируешь прошлые решения.


Не стыдиться, а учиться

Такой код — не позорное пятно, а материал для роста. Каждый «студенческий скрипт» в продакшне — это напоминание, что софт живёт дольше, чем мы думаем. И если мы научимся принимать это наследие, учиться у него и постепенно улучшать — то даже самые кривые костыли могут стать точками опоры.

Так что, если завтра вы откроете репозиторий и увидите там свои старые строчки, не ругайте себя. Лучше спросите: «А чему этот код может меня научить сегодня?»

Комментарии (0)