← назад к разделу

Команда работает по Scrum: есть sprint, есть backlog, каждые две недели — демо. Процесс выстроен, но релизы всё равно страшные. Каждое обновление рискует что-то сломать, тесты гоняют вручную перед выкаткой, а после мержа большой ветки полдня уходит на разбор конфликтов. Проблема не в процессе — процесс как раз в порядке. Проблема в том, как написан код: он не готов к тому, чтобы меняться часто и безопасно.

Extreme Programming (XP) — методология, которая закрывает именно этот пробел. Scrum и Kanban отвечают на вопрос «как организовать поток работы»: кто что берёт, когда планируем, как показываем результат. XP отвечает на другой вопрос — «как писать и менять код, чтобы быстрые итерации не превращались в накопление проблем». Это набор инженерных практик, а не церемоний. Разберём, из чего он состоит и почему части этого набора давно стали стандартом индустрии.

круг: красный тест → минимальный код → зелёный → чистка тест красный код минимум чистка зелёный тесткрасный кодминимум чистказелёный проверка написана тест зелёный поведение то же следующий тест пара: ревью в момент письма,а не через день в pull request сеть проверок не больше половиныкрасный не больше половинызелёный возврат при отменекрасный кода ещё нет def bonus_payable(total, balance): if balance < total // 2:return balancereturn total // 2 return min(balance, total // 2)структура другая, поведение то же —проверка сверху всё ещё зелёная

Круг слева и его следы справа. Проверку пишут первой — она красная, потому что кода ещё нет. Минимальный код делает её зелёной. Потом код чистят: строк меньше, проверка та же и остаётся зелёной — это и есть доказательство, что поведение не поехало. Дальше круг начинается заново для следующего поведения, а сеть проверок растёт и страхует всё, что чистят потом.

Идея: процесс и инженерия — это разные оси

Легко перепутать XP со Scrum, потому что оба относятся к Agile. Но они про разное и хорошо сочетаются.

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

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

Отсюда простое правило: если что-то полезно делать — делай это постоянно и доводи до предела. Тестирование полезно — значит, пишем тесты на всё и всегда. Интеграция полезна — значит, интегрируемся по несколько раз в день, а не раз в спринт. Отсюда и слово «extreme».

Практики: как XP делает изменения дешёвыми

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

Test-Driven Development (TDD). Тест пишется раньше кода. Сначала — маленький тест, который описывает ожидаемое поведение и пока падает. Потом — минимальный код, чтобы тест прошёл. Потом — чистка. Цикл называют «red — green — refactor». Смысл не только в покрытии: тест, написанный первым, заставляет продумать интерфейс до реализации и оставляет за собой сеть проверок, которая ловит поломки при каждом изменении.

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

живой пример

def run(rule):
    cases = [((1000, 800), 500), ((1000, 300), 300), ((0, 300), 0)]
    for (total, balance), expected in cases:
        got = rule(total, balance)
        if got != expected:
            return f"красный: заказ {total}, баланс {balance} — ждали {expected}, вышло {got}"
    return f"зелёный: {len(cases)} из {len(cases)}"

print(run(lambda total, balance: balance))
print(run(lambda total, balance: balance if balance < total // 2 else total // 2))
print(run(lambda total, balance: min(balance, total // 2)))
Запустить

Запуск примеров доступен в платном доступе. Там этот же код выполняется прямо в статье: редактор, запуск и проверка рядом с абзацем. Неделя бесплатно →

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

Парное программирование (pair programming). Двое работают за одной задачей: один пишет код, второй думает на шаг вперёд — про краевые случаи, имена, дизайн. Роли меняются. Это непрерывное ревью в реальном времени: ошибки ловятся в момент написания, а не через день в pull request. Плюс знание о коде не запирается в одной голове.

Непрерывная интеграция (Continuous Integration, CI). Каждый вливает свои изменения в общую ветку часто — несколько раз в день, а не копит их неделями. На каждое вливание автоматически собирается проект и прогоняются тесты. Маленькие частые слияния почти не дают конфликтов; редкие большие — дают болезненные.

Рефакторинг. Улучшение структуры кода без изменения его поведения. Переименовать, разбить длинный метод, убрать дублирование. В XP это не отдельная «фаза уборки раз в квартал», а постоянная гигиена: увидел, что стало запутанно — почистил сразу. Именно тесты делают рефакторинг безопасным: если после перестановки код зелёный, поведение не изменилось.

Коллективное владение кодом. Любой участник команды имеет право править любую часть кода. Нет «это модуль Пети, к нему только Петя». Так исчезают точки, где всё встаёт из-за отсутствия одного человека, и любой может провести нужное улучшение там, где его заметил.

Простой дизайн и YAGNI. Принцип «You Aren't Gonna Need It» — не строй абстракцию под гипотетическое будущее требование. Делай самое простое решение, которое работает сейчас и покрыто тестами. Когда требование реально придёт — рефакторинг и тесты позволят безопасно расширить дизайн. Заранее заложенная «гибкость на всякий случай» чаще становится грузом, чем помогает.

Частые маленькие релизы. Выкатывать небольшими порциями и часто. Маленький релиз легче протестировать, легче откатить и быстрее даёт обратную связь от реальных пользователей. Большой редкий релиз копит риск и откладывает момент, когда узнаёшь, что что-то пошло не так.

Обратная связь на всех уровнях

Если посмотреть на практики XP вместе, видно общий мотив: сократить время между «сделал что-то» и «узнал, к чему это привело». Чем короче петля обратной связи, тем дешевле ошибка — её ловят, пока она свежая и маленькая.

Петля обратной связиЧто даётСкорость
Тест (TDD)сломал поведение — узнал сразусекунды
Параплохое имя или краевой случай — заметили при написанииминуты
CIконфликт или красная сборка — узнали при вливанииминуты
Маленький релизне то поведение для пользователя — увидели быстрочасы–дни
Спринт-демо (Scrum)не ту функцию делаемнедели

Каждый уровень ловит свой класс проблем и на своём масштабе времени. Тест не заметит, что вы делаете не ту функцию, — это увидит демо. Демо не заметит опечатку в условии — это поймает тест. XP старается, чтобы на каждом масштабе была своя быстрая проверка, а не одна медленная в самом конце.

Что прижилось повсеместно, а что реже

XP сложился на проекте Chrysler в 1996 году, книга Кента Бека «Extreme Programming Explained» вышла в 1999-м — и звучал он тогда радикально. С тех пор индустрия «переварила» его практики неравномерно: часть стала стандартом де-факто, часть встречается реже.

Прочно вошли в обиход:

  • TDD — как минимум в форме сильной культуры автотестов; писать код без тестов сегодня считается плохим тоном в большинстве команд.
  • Непрерывная интеграция — сегодня это база: CI-конвейер, который на каждый коммит собирает проект и гоняет тесты, есть почти везде. Из него выросли CI/CD-практики частой автоматической доставки.
  • Рефакторинг — стал обычной частью ежедневной работы, поддержан инструментами в любой IDE.
  • Простой дизайн и YAGNI — вошли в общий словарь как здравый принцип против переусложнения.

Применяется реже и выборочно:

  • Парное программирование на весь рабочий день — практикуют не все. Оно дорого по времени и утомительно, поэтому чаще используют его точечно: для сложных задач, введения в проект новых людей или разбора запутанного участка. Частичную замену дают асинхронные ревью в pull request.
  • Полное коллективное владение — в больших организациях смягчается: часто есть «владельцы» подсистем, отвечающие за архитектурные решения, при этом мелкие правки разрешены всем.

Даже команда, которая не называет себя «XP-командой», почти наверняка живёт на его практиках: TDD, CI, рефакторинг и простой дизайн стали общим фоном инженерной культуры — и именно они делают частые релизы, которые обещает Agile, действительно безопасными.

Коротко

  • XP отвечает не на вопрос «как организовать работу» (это Scrum и Kanban), а на вопрос «как писать код, чтобы частые изменения были дешёвыми и безопасными».
  • Центральная идея — стоимость изменения не обязана расти со временем; при правильных практиках кривая остаётся пологой.
  • Ключевые практики: TDD (тест раньше кода), парное программирование, непрерывная интеграция, рефакторинг, коллективное владение, простой дизайн (YAGNI), частые маленькие релизы.
  • Практики усиливают друг друга: тесты делают рефакторинг безопасным, CI ловит конфликты рано, пара даёт ревью в реальном времени.
  • Общий принцип — короткие петли обратной связи: тест реагирует за секунды, пара и CI за минуты, релиз за часы, демо за недели.
  • TDD, CI, рефакторинг и YAGNI стали стандартом де-факто; парное программирование на весь день и полное коллективное владение применяют реже — точечно или в смягчённой форме.

Что почитать дальше

  • Пирамида тестов — как устроить автотесты так, чтобы TDD давал быструю обратную связь.
  • Принципы CI/CD — во что выросла непрерывная интеграция: автоматическая сборка, тесты и доставка на каждый коммит.
  • Clean Code — принципы, на которые опирается рефакторинг и простой дизайн.
  • Scrum — процессная методология, с которой XP хорошо сочетается: разные оси одной задачи.