Мы все пишем код, но редко задумываемся, сколько он проживёт без нас. Этот текст — о выживании кода во времени: как писать так, чтобы через пять лет проект не превратился в болото. Без догматизма, с примерами, с болью и, надеюсь, с долей самоиронии.

Код — как археологический слой
Иногда открываешь старый проект и ловишь себя на мысли: «Кто вообще писал этот ужас?» А потом смотришь в git blame — и видишь своё имя.
Это странное чувство — когда твой собственный код становится для тебя загадкой. И ведь дело не в памяти. Просто тогда ты думал иначе. Уровень абстракции, спешка, корпоративные дедлайны — всё наложилось, и через год результат кажется чужим.
Долговечный код — это не про язык, не про фреймворк, а про то, чтобы спустя годы твои идеи всё ещё можно было прочитать. Как хорошую книгу, где не нужно лезть в документацию, чтобы понять, кто герой и зачем он вообще живёт.
И если честно, долговечность — не про будущее. Это про уважение к тем, кто придёт после нас. Даже если этим «кем-то» окажетесь вы сами через полгода.
Минимализм как стратегия выживания
Когда систему собирают в спешке, она растёт не вверх, а вширь. Слой на слое. Каждый новый разработчик добавляет «ещё немного логики», и в какой-то момент код перестаёт быть предсказуемым.
Минимализм в программировании — не эстетика, а способ выжить. Он требует дисциплины: писать не всё, что можно, а только то, что нужно.
Пример. Вы работаете над API для учёта пользователей. У вас есть соблазн сделать гибкий универсальный слой валидации, который сможет проверять всё. Звучит круто, пока не начинаешь поддерживать это.
Вместо универсального монстра можно написать просто и честно:
# Python 3.12
def validate_user(user: dict) -> bool:
if not user.get("email") or "@" not in user["email"]:
return False
if len(user.get("password", "")) < 8:
return False
return True
Просто, читаемо, расширяемо.
Да, кто-то скажет: «Но ведь нет ни логгирования, ни исключений, ни гибкой схемы». И будет прав. Но если система проживёт дольше, чем ваше желание «улучшить всё сразу» — значит, минимализм сработал.
Минимализм — это не отказ от технологий, это отказ от иллюзии, что код должен быть «идеально умным».
Читаемость: чтобы через пять лет не писать себе письмо с расшифровкой
Хороший код читается сверху вниз, как рассказ. Он не заставляет гадать, зачем эта функция существует.
Есть простое правило, которое я применяю к себе: если код не читается вслух, он не читаем вовсе.
Вот пример. Допустим, мы пишем обработчик сообщений для внутреннего брокера:
// Go 1.23
func HandleEvent(e Event) error {
if e.Type == "user_deleted" {
return cleanupUserData(e.ID)
}
if e.Type == "user_created" {
return provisionDefaults(e.ID)
}
return fmt.Errorf("unknown event: %s", e.Type)
}
Смысл понятен без контекста. Можно не знать всю систему, чтобы догадаться, что происходит.
Теперь представьте ту же логику, но через три слоя абстракций, DI-контейнер и пачку generic-хелперов. Код вроде «модульный», но если нужно быстро починить — ты тонешь в слоях.
Читаемость — это не когда красиво. Это когда не больно.
Долговечность: код, который не стареет вместе с фреймворком
В больших системах долговечность редко рушится из-за багов. Её убивают зависимости.
Мы все знаем этот сценарий: новая версия фреймворка ломает обратную совместимость, пакет больше не поддерживается, CI перестаёт собирать проект.
Чтобы код прожил долго, нужно уменьшить площадь контакта с внешним миром. Чем меньше библиотек завязано на конкретную версию, тем лучше.
Пример из практики — один старый сервис на Python, написанный в 2017-м. Мы решили обновить FastAPI, и всё рухнуло. Причина была банальной: внутренняя зависимость на приватные части библиотеки.
Вместо того чтобы править всё, я тогда выделил слой обёрток:
# Python 3.12
class APIResponse:
def __init__(self, data: dict, status: int = 200):
self.data = data
self.status = status
def json_ok(data: dict) -> APIResponse:
return APIResponse(data)
def json_error(message: str, code: int = 400) -> APIResponse:
return APIResponse({"error": message}, code)
Этот слой прожил уже три версии FastAPI. И дело не в гениальности кода, а в том, что он изолирован.
Долговечность — это не когда код не ломается. Это когда его можно чинить, не переписывая всё вокруг.
Код как коллективная собственность
Если вы работаете в команде, код принадлежит не вам. И вот это, пожалуй, самая трудная истина.
Когда мы пишем что-то сложное, хочется оставить «свой стиль». Но чем больше индивидуальности, тем труднее другим. Долговечный код — это не произведение искусства. Это инструкция, которая должна быть понятна каждому, кто её откроет.
Здесь помогает культура комментариев. Не тех, что объясняют очевидное, а тех, что раскрывают замысел:
// Rust 1.81
// Используем atomic swap, чтобы избежать блокировки при обновлении состояния.
// Это критично, потому что операция вызывается из нескольких потоков.
fn update_state(new_state: State) {
STATE.swap(Arc::new(new_state));
}
Когда читаешь такой комментарий через год, сразу ясно: человек знал, зачем он делает именно так. И даже если архитектура изменится, логика останется читаемой.
Пишите комментарии как письма будущим коллегам. Или себе — но более умному.
Финал. О честности перед будущим
Писать долговечный код — значит, быть немного скучным. Не гнаться за хайпом, не вставлять новые фреймворки ради резюме, не делать умнее, чем нужно.
Парадоксально, но лучший комплимент коду через пять лет — не «вау, гениально», а «ничего не пришлось менять».
Задайте себе вопрос: если завтра вы уйдёте, сможет ли кто-то поддерживать ваш проект без боли? Если ответ «да» — значит, вы написали код, который переживёт вас.
Комментарии (7)

TimurZhoraev
20.10.2025 11:53Идеальный вариант - не сам код а человеко- и машиночитаемая на него документация с формулами LaTeX (этот язык наравне с Лиспом для систем компьютерной алгебры и Фортраном, переживёт что угодно)

aaveter
20.10.2025 11:53Хорошо, но мало. В реальных проектах кода много. Одну простую функцию, да, легко сделать читаемой. Но что делать с 5000+ строчек кода в файле...
2medic
Ответ — никак. Когда-то я писал под ДВК-3 офигительно крутые проекты по управлению лабораторными стендами для изучения явления индукции и гистерезиса. В стендах использовался цифровой осциллограф, я управлял им через КОП, строил графики, аппроксимируя результаты и дополняя их недостающими данными, и тогда мне казалось, что я пишу код, который переживёт меня.
Но сейчас этот код там же, где и сами ДВК — на помойке. Никто не сможет его запустить. И это вовсе не из-за багов или плохого стиля — железо умерло, протоколы устарели, интерфейсы исчезли.
Долговечность кода возможно только в мире, где инфраструра стабильно поддерживает обратную совместимость.
А в реальном проекте, где железо и фреймворки «умирают», всё превращается в артефакт: код вроде есть, но выполнить его уже нельзя.
rikert
Ждем смерти x86 и говнокодим?