Технический долг

Автор оригинала: Martin Fowler
  • Перевод
Программные системы склонны к накоплению мусора — внутренних недоработок, которые затрудняют дальнейшее изменение и расширение системы по сравнению с идеальным кодом. Технический долг — это метафора, придуманная Уордом Каннингемом. Она объясняет, как воспринимать этот мусор, по аналогии с финансовым кредитом. Дополнительные усилия, необходимые для добавления новых функций, — это проценты по кредиту.



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

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

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

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

Сравнение выплаты процентов с выплатой основного долга помогает определить, с каким мусором разбираться. Если у меня есть какая-то особо ужасная область кодовой базы, то проблема исчезает, если выясняется, что мусор невыгодно удалять. Проценты выплачиваются только тогда, когда приходится работать с этой частью программного обеспечения (в этом месте метафора немного хромает, потому что по банковскому кредиту нужно платить всегда). Таким образом, кошмарные, но стабильные области кода можно оставить в покое.

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

Метафора долга иногда используется для оправдания низкого качества кода. Аргумент состоит в том, что качественный код требует больше времени и усилий. Если срочно нужны новые функции, лучше принять на себя долг и разбираться с ним потом

Опасность здесь в том, что зачастую этот анализ ошибочен. Мусор очень быстро начинает вредить, замедляя внедрение новых функций. В итоге разработчики превышают кредитные лимиты и выпускают продукт позже, чем если бы сразу потратили время на обеспечение более высокого качества. Здесь метафора часто вводит людей в заблуждение, поскольку динамика технического долга на самом деле не соответствует динамике финансовых кредитов. Принятие на себя долга для ускорения выпуска продукта работает только в том случае, если вы остаётесь ниже линии design payoff в гипотезе об устойчивости архитектуры, а разработчики пересекают её уже через несколько недель, а не месяцев.



Регулярно ведутся дебаты о том, следует ли считать долгом различные виды мусора. Мне кажется, тут полезно учитывать, берётся долг сознательно и разумно — или безрассудно. Так появился квадрат технического долга.

Дальнейшее чтение


Насколько я могу судить, Уорд впервые представил эту концепцию в отчёте для OOPSLA 1992. Она также обсуждалось в вики.

Есть видеозапись, где Уорд Каннингем обсуждает придуманную им метафору.

Дэйв Николетт расширяет взгляд Уорда на технический долг, приводя прекрасный пример того, что я называю разумным преднамеренным долгом.

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

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

Стив Макконнелл выделил в метафоре несколько хороших моментов. В частности, как уменьшение непреднамеренного долга оставляет больше возможностей намеренно принять долг, когда это полезно. Мне также нравится его формулировка минимальных платежей (которые слишком высоки, чтобы исправить проблемы во встраиваемых системах, но не на сайтах).

Аарон Эриксон говорил о финансировании Enron.

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

Эрик Дитрих обсуждает человеческие потери из-за технического долга: сражения в командах, деградация навыков и выгорание.

Правки


Первоначально этот пост был опубликован 1 октября 2003 года. Я полностью переписал его в апреле 2019 года.
  • +19
  • 5,3k
  • 2
Поддержать автора
Поделиться публикацией

Комментарии 2

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

      Понравилась метафора "технический налог": Мы принимаем, что появление технического долга неизбежно, это не решение берём долг или не берём, он появляется "сам", в наших силах лишь стараться уменьшать налоговую базу и вовремя и регулярно платить, чтоб не допускать снежного кома пеней и штрафов. То есть в наших силах стараться не допускать появление большого долга при разработке с одной стороны, а, с другой, постоянно выделять часть ресурсов, например 10 или 20% рабочего времени непосредственно на его целенаправленное погашение. Редко же кто планирует уплату налогов по принципу "будут свободные деньги после релиза — заплачу, а пока есть более важные траты". Часто налоги платят даже раньше конечного срока уплаты. Да, иногда принимаются решения просрочить уплату, но с чётким пониманием, что а) заплатить придётся б) больше чем вовремя в) следующих платежей это не отменит и г) бьёт по репутации. Грубо говоря, можно принять решение день, отведенный в каждом спринте на рефакторинг, дописывание тестов, устранения причин варнингов и нотисов в разных логах и отчётах, обновление зависимостей и прочая, и прочая, и прочая, забрать для завершения важной фичи, но чётко понимая, что в следующем спринте это будет уже два дня (перенесеный день плюс "родной" день следующего спринта) плюс несколько часов "пеней и штрафов".

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

      Самое читаемое