Подробные статьи о технологиях, определяющих будущее.

Почему хороший софт требует времени и не терпит спешки

Почему лучшие программные проекты создаются годами, а не месяцами. Аргументы в пользу терпения в разработке: от open source до стартапов.

Аккуратно подрезанное бонсай на деревянном столе, растущее из открытого ноутбука

Flask шёл к версии 1.0 восемь лет. SQLite активно развивается с 2000 года и до сих пор получает существенные улучшения. Ядру Linux больше трёх десятилетий, и его можно без преувеличения назвать лучше с возрастом. Тем временем от венчурного стартапа обычно ждут заметной тяги в течение 18 месяцев или объяснения, почему её нет.

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

Миф о внезапном успехе

Почти у каждого «внезапного успеха» в software есть долгая предыстория. React несколько лет использовался внутри Facebook, прежде чем его открыли. Rust разрабатывался семь лет до выхода версии 1.0. PostgreSQL начинался как исследовательский проект в 1986 году и стал основной production-базой данных только в 2010-х, то есть почти через 30 лет тихого и стабильного совершенствования.

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

Армин Ронахер, создатель Flask, писал об этом прямо. Flask начинался как шутка на 1 апреля в 2010 году. Серьёзным проектом он стал почти случайно. Годы постепенной работы, исправление пограничных случаев, улучшение документации, пересмотр API превратили его в один из самых популярных Python-фреймворков для веба. Ни один из этих лет не был потрачен впустую. Каждый из них укреплял фундамент.

Почему у софта есть неустранимая временная составляющая

Некоторые задачи нельзя решить быстрее, добавив людей или поднажав. Фред Брукс описал это в 1975 году в книге Мифический человеко-месяц, и её главная мысль не устарела: некоторые аспекты разработки софта последовательны и не распараллеливаются.

  • Понимание предметной области. Нельзя по-настоящему понять проблемную область, пока ты в ней не поработал какое-то время. Первая версия любого софта кодирует ваши изначальные предположения. Вторая кодирует то, что вы узнали из первой. Настоящее понимание требует итераций, а итерации требуют времени.
  • Дизайн и стабильность API. Хорошие API рождаются из использования. Идеальный API в вакууме не спроектируешь, нужны реальные пользователи, которые натыкаются на реальные пограничные случаи. Библиотеки, которые торопятся с версией 1.0, потом годами жалеют о ранних решениях по дизайну.
  • Пограничные случаи и доработка. Первые 80% функциональности занимают 20% времени. Оставшиеся пограничные случаи, обработка ошибок и особенности платформ отнимают остальные 80%. Это соотношение не лень, а фундаментальная природа создания надёжного софта.
  • Сообщество и экосистема. Инструмент по-настоящему полезен только тогда, когда у него есть документация, туториалы, плагины и сообщество, которое отвечает на вопросы. Такую экосистему нельзя изготовить искусственно, она вырастает органически и со временем.

Вред искусственной срочности

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

Я видел, как несколько перспективных open source проектов развалились, потому что пытались расти быстрее, чем их фундамент мог выдержать. Сценарий предсказуем: проект становится популярным, мейнтейнеры чувствуют давление и быстро выпускают фичи, качество падает, контрибьюторы выгорают, а пользователи уходят к чему-то более стабильному. Ирония в том, что замедление помогло бы им уйти гораздо дальше.

Долго живут не те проекты, которые выпустились быстрее всех. Долго живут те, которые рано приняли хорошие решения и поэтому не были вынуждены переписывать всё позже.

Технический долг — это не только грязный код. Это решения, принятые под давлением сроков, которые ограничивают будущие возможности. Каждая попытка срезать путь ради скорости выпуска — это налог на каждое будущее изменение. Некоторые срезания стоят того, но делать их нужно осознанно, а не потому, что кто-то произвольно решил, что дедлайн в следующий вторник.

Как выглядит терпение на практике

Терпение в разработке не означает двигаться медленно ради самого движения. Оно означает обдуманность в том, что вы строите, и честность в оценке того, сколько всё занимает времени. Несколько практик, которые, как я видел, хорошо работают:

  • Выпускайте рано, но обязательства берите медленно. Выкатывайте софт пользователям быстро, чтобы получать обратную связь, но будьте очень осторожны с тем, что фиксируете как стабильный API. Щедро используйте версии 0.x и явно давайте понять, что всё может измениться.
  • Говорите «нет» фичам. Каждая добавленная фича — это то, что вы будете поддерживать вечно. Лучшие проекты имеют чёткое мнение о своих границах. SQLite открыто перечисляет то, что никогда не будет делать, и именно эта дисциплина делает его самой развёрнутой базой данных в мире.
  • Инвестируйте в фундамент. Документация, тестирование, понятные сообщения об ошибках, производительность — это не блестяще, но эффект накапливается. Хорошо документированный проект с крепким набором тестов на третьем году может двигаться быстрее, чем плохо документированный на первом.
  • Берегите силы мейнтейнеров. Выгорание — главный убийца open source проектов. Устойчивый темп важнее спринтовой скорости. Мейнтейнер, который пять лет работает по 20 сфокусированных часов в неделю, сделает больше, чем тот, кто полгода работает по 80 часов в неделю, а потом исчезает.

Ловушка скорости в стартапах

Стартапы сталкиваются с законным противоречием: им нужно двигаться быстро, чтобы выжить, но слишком быстрое движение создаёт хрупкие системы, которые становятся обузой при масштабировании. Те компании, которые справляются с этим хорошо, как правило, различают два типа скорости.

Скорость итераций — насколько быстро вы можете проверять идеи, получать отклик пользователей и менять направление. Её нужно максимизировать. Короткие циклы, быстрое прототипирование, готовность выбросить сделанное.

Скорость принятия обязательств — насколько быстро вы фиксируете архитектурные решения, публичные API и модели данных. Её нужно минимизировать. Держите всё обратимым как можно дольше. Чем дольше вы откладываете необратимые решения, тем больше информации у вас будет, когда вы наконец их примете.

Большинство стартапов ошибаются, когда смешивают эти два вида скорости. Они фиксируют архитектуру так же быстро, как итерируют фичи, а потом два года платят налог за преждевременные решения.

Что нам дают проекты, которые выжили

Софт, на который мы опираемся сильнее всего, объединяет общая черта: в какой-то момент его считали «медленным». PostgreSQL был скучным выбором, тогда как MySQL считали быстрым и необязательным. Python называли «слишком медленным», а Perl считали прагматичным выбором. Git несколько лет был неудобен для обычных людей.

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

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

Некоторые вещи просто требуют времени. Лучшая реакция — не бороться с этой реальностью, а строить системы, команды и ожидания, которые это учитывают.