Как я могу определить количество технической задолженности, существующей в проекте?

67

Кто-нибудь знает, есть ли какой-то инструмент для обозначения числа технических долгов кодовой базы, в качестве метрики кода? Если нет, кто-нибудь знает алгоритм или набор эвристики для него?

Если ни одна из этих вещей не существует до сих пор, я бы заинтересовался идеями о том, как начать такую ​​вещь. То есть, как я могу количественно оценить техническую задолженность, возникшую у метода, класса, пространства имен, сборки и т. Д.

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

Эрик Дитрих
источник
12
Технический долг зависит от решений, а не от кода. Это накапливается из-за плохих управленческих решений. Не ясно, что «метод, класс, пространство имен, сборка» сами по себе содержат технический долг. Они представляют собой ответственность, когда есть лучший выбор.
S.Lott
7
Я бы сказал (в контексте метафоры долга), что управляющие могут быть держателями долга, но артефакты кода представляют оценку долга и могут быть определены количественно. То есть я согласен с тем, что менеджеры могут принять решение, например, «забыть юнит-тестирование, потому что у нас нет времени», и, таким образом, получить технический долг. Но я, конечно, думаю, что вы можете поместить число в отдельные элементы кода как эвристику. Подумайте об этом так: если руководство принимает ряд ужасных решений на будущее, но код не был написан, есть ли долг в этот момент?
Эрик Дитрих
3
"Есть ли долг в этот момент?" Долг надо накапливать, ты прав. Но это не код; это объем «проделанной работы», который нужно отменить. Спецификации, проекты, код, DBA-работа, все это должно быть переработано. Измерение задолженности по программным артефактам (например, по строкам исходного кода) похоже на прогнозирование стоимости разработки.
S.Lott
7
Измерение технического долга сложно, плюс оно сбивает с толку менеджеров. Тем не менее, я могу сказать вам хороший способ борьбы с техническими долгами: дешевые, хорошие и работающие прототипы, особенно если база кода вращается вокруг GUI. Как предложил Джоэл: joelonsoftware.com/articles/fog0000000332.html , каждый день уделяйте немного времени уборке. Изменения должны быть положительными улучшениями, а не «OMG, наша техническая задолженность = пентаблобы, и она растет в геометрической прогрессии со скоростью ... небо падает». Просто проводите немного времени каждый день на кайдзен таким образом, чтобы не сломать вещи, которые работают. Заводить друзей.
Работа
6
@ZoranPavlovic В вашей причудливой и незапрошенной ложной дилемме отсутствует третий вариант: я хотел знать, есть ли какие-либо инструменты, которые пытались количественно оценить технический долг.
Эрик Дитрих

Ответы:

38

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

Существует ряд метрик, которые могут дать вам некоторое представление о качестве кода:

  • Кодовое покрытие. Существуют различные инструменты, которые сообщают вам, какой процент ваших функций, операторов и строк покрывается модульными тестами. Вы также можете сопоставить системные и приемочные тесты с требованиями, чтобы определить процент требований, покрываемых системным тестом. Соответствующее покрытие зависит от характера заявки.
  • Сцепление и сцепление . Код, демонстрирующий слабую связь и высокую когезию, обычно легче читать, понимать и тестировать. Существуют инструменты анализа кода, которые могут сообщать о степени сцепления и сцепления в данной системе.
  • Цикломатическая сложность - это число уникальных путей через приложение. Обычно это считается на уровне метода / функции. Цикломатическая сложность связана с понятностью и тестируемостью модуля. Не только более высокие значения цикломатической сложности указывают на то, что у кого-то будет больше проблем с выполнением кода, но и цикломатическая сложность также указывает на количество тестовых случаев, необходимых для достижения охвата.
  • Различные меры сложности Halstead обеспечивают понимание читаемости кода. Они подсчитывают операторов и операндов, чтобы определить объем, сложность и усилие. Часто это может указывать на то, как трудно будет кому-то подобрать код и понять его, часто в таких случаях, как проверка кода или новый разработчик базы кода.
  • Количество повторяющегося кода. Дублированный код может указывать на возможность рефакторинга для методов. Наличие дублированного кода означает, что для появления ошибки существует больше строк, и более высокая вероятность того, что одни и те же дефекты существуют в нескольких местах. Если одна и та же бизнес-логика существует в нескольких местах, становится сложнее обновить систему, чтобы учесть изменения.

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

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

Томас Оуэнс
источник
1
В настоящее время я использую метрики кода NDepend ( ndepend.com ), CodeRush и VS, чтобы следить за метриками, которые вы упоминаете (за исключением мер Хэлстеда, о которых я расскажу далее). Я подумал, что мог бы использовать некоторое объединение этих метрик, чтобы попытаться поместить какое-то число в данный элемент кода, которое примерно показало бы, на первый взгляд, насколько дорого это было для продолжающейся разработки.
Эрик Дитрих
@ErikDietrich Возможно, вы сможете, но я бы не стал определять это значение. Возможно, более уместным будет отчет в стиле «резюме» о том, что ваши инструменты метрики сообщают вам относительно изменений во времени.
Томас Оуэнс
2
Еще одна простая метрика, которую я бы добавил в список, это число TODO / HACK / WTF? комментарии в кодовой базе ...
MaR
@Mar Это предполагает, что вы правильно используете их, а не играете в них в ваших интересах. Нужно дополнительное время для очистки базы кода, просто добавьте эти комментарии там, где они не подходят. Не заботьтесь о базе кода, просто удалите их там, где они должны быть. Комментарии могут лгать, код не может.
Томас Оуэнс
1
@ Томас Оуэнс: согласен, но почти любой показатель может быть обманут. При правильном и честном использовании «метрика TODO» предоставляет дешевый обзор того, какой код фактически отсутствует или должен быть изменен (= невидимый долг для метрик, основанных только на коде).
MaR
23

У Sonar есть техническая эвристика долга, а также ряд других функций, полезных для программного проекта.

Он также поддерживает довольно широкий спектр языков.

SonarQube (ранее Sonar ) - это платформа с открытым исходным кодом для непрерывного контроля качества кода ...

  • Поддержка более 25 языков: Java, C / C ++, C #, PHP, Flex, Groovy, JavaScript, Python, PL / SQL, COBOL и т. Д.
  • SonarQube также используется в Android Deveopment.
  • Предлагает отчеты по дублированному коду, стандартам кодирования, модульным тестам, охвату кода, сложному коду, потенциальным ошибкам, комментариям, дизайну и архитектуре.
  • Машина времени и дифференциальные представления.
  • Полностью автоматизированный анализ: интегрируется с Maven, Ant, Gradle и инструментами непрерывной интеграции (Atlassian Bamboo, Jenkins, Hudson и т. Д.).
  • Интегрируется со средой разработки Eclipse
  • Интегрируется с внешними инструментами: JIRA, Mantis, LDAP, Fortify и др.
  • Расширяется с использованием плагинов.
  • Реализует SQALE методологии для расчета технического долга ...
Роберт Грайнер
источник
1
Хорошо, спасибо! Я использую и использую NDepend для своей работы на C #, но я также немного работаю с Java и интересуюсь метриками там же. По крайней мере, это дает мне функциональность для Java, и может оказаться хорошим дополнением к NDepend.
Эрик Дитрих
Круто, мы используем Sonar, где я работаю, и он делает несколько действительно приятных вещей, которые дают вам представление о состоянии вашей кодовой базы.
Роберт Грайнер,
2
@ErikDietrich, FYI Sonar также имеет плагин C # .
Петер Тёрёк
@ErikDietrich FYI есть теперь плагин NDepend для эхолота ndepend.com/docs/sonarqube-integration-ndepend
Патрик Smacchia - NDepend DEV
Есть ли альтернативы с открытым исходным кодом?
Хеллбой
5

Я ненавижу использовать аналогию с финансами, но она кажется действительно уместной. Когда вы оцениваете что-то (активы любого рода), это может иметь как внутреннюю, так и внешнюю ценность. В этом случае существующий код имеет внутреннее значение, которое будет величиной, соответствующей относительному качеству указанного кода, и он также будет иметь внешнее значение (значение из того, что можно сделать с кодом), и эти величины будут аддитивными. Внутренняя ценность может быть разбита на кредиты и дебеты (хорошие или плохие), используя любую методологию, которую вы используете для оценки кода (+5 для комментариев / читаемости, -10 для покрытия кода и т. Д.)

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

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

сопоставление с образцом
источник
Да, концепция уменьшения предельной доходности - это, безусловно, то, к чему я бы хотел обратиться при разработке и уточнении метрики. Таким образом, не только «вот мой объективный аргумент в пользу рефакторинга этого класса с точки зрения бизнеса», но и «вот мое обоснование того, чтобы не беспокоиться на данном этапе».
Эрик Дитрих
5

Между разработчиками довольно надежным показателем технической задолженности является WTFs / мин .

Проблема с этим «показателем» состоит в том, что обычно довольно сложно общаться «снаружи».

Метрикой, которая работала для меня при сообщении технического долга «посторонним», было количество испытаний и исправление ошибок (особенно для исправления ошибок регрессии ), необходимых для успешной доставки.

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

  • гораздо проще указать 3 недели, потраченные на реализацию функции А, чем
     
    я потратил 14 часов на предварительную реализацию функции А, затем 29 часов на тестирование дыма, затем 11 часов на внедрение исправлений для обнаруженных мною регрессий, а затем 18 часов на тестирование QA. уже реализована функция. После этого ребята из QA потратили 17 часов на тестирование первоначального релиза кандидата. После этого я потратил 13 часов на анализ ошибок, представленных QA для первоначального выпуска кандидата, и 3 часа на внедрение исправлений. После этого я потратил 11 часов на тестирование дыма на предмет изменений, внесенных в первоначальный выпуск кандидата. После того...

В любом случае, по моему опыту, данные о тестировании и исправлении ошибок было довольно легко передать.

В последнем выпуске мы потратили около 90% времени на тестирование и исправление ошибок регрессии. Для следующего выпуска предложите приложить некоторые усилия для снижения этого значения до 60-70%.


Еще одно слово предостережения. Данные, как 90% выше, могут быть интерпретированы не только как показатель технического долга, но также (неожиданный сюрприз) как признак того, что вы не совсем разбираетесь в программировании / конкретной технологии. «Вы просто делаете слишком много ошибок в своем коде».

Если существует риск неверного толкования данных, это помогает иметь дополнительные справочные данные о чем-то менее подверженном WTF для сравнения.

  • Скажем, если есть два одинаковых компонента / приложения, поддерживаемых одним и тем же разработчиком, первый из которых выпускает с «нормой отходов» около 50%, а второй - 80–90, это дает достаточно веские основания в пользу того, что второй является предметом технического долга.

Если в проекте есть специальные тестировщики, они также могут способствовать более объективной оценке данных. Как я уже упоминал в другом ответе ,

С помощью тестировщиков вы получите кого-то, кто подтвердит ваше понимание проблем проектирования. Когда только разработчики жалуются на качество кода , это часто звучит как субъективные WTF из-за закрытой двери .
 
Но когда это подтверждается парнем из QA, который говорит что-то вроде component A100 регрессионных ошибок для 10 новых функций, в отличие от component B10 регрессивных ошибок на 20 новых функций , общение внезапно превращается в целую другую игру.

комар
источник
2
Мне очень нравится этот ответ. С выделенным отделом QA соотношение регрессионных дефектов к новым дефектам очень просто рассчитать и может определенно рассказать вам много о технической задолженности.
Эрик Дитрих
4

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

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

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

Мэтью Флинн
источник
Итак, в контексте сюжетных моментов, справедливо ли сказать, что вы могли бы добавить несколько моментов к каждому сюжету, если в затронутых областях кода была высокая техническая задолженность? То есть, если история X включает в себя добавление к элементу кода Y, что просто ужасно, вы указываете несколько моментов на историю именно из-за природы Y? И это количество баллов совпадает или связано с количеством баллов для выполнения исправления, которое вы упомянули, оценивая?
Эрик Дитрих
1
@ Эрик Дитрих - ТД определенно добавляет сложности в решение. Сложность может заключаться в том, что починка TD может быть более дорогостоящей, чем оптовое решение. Таким образом, может случиться так, что у вас есть 3 истории, которые будут оценены по 5, если бы TD был исключен, но по 8 с долгами на месте - так что в сумме получается 9 баллов TD. Задача исправить ТД в целом (независимо от истории) может фактически быть 8. Таким образом, вы можете утверждать, что оптовое решение стоит меньше (8), чем частичное (9). Это будет частью переговоров
Мэтью Флинн
Это имеет смысл. И, конечно же, то, к чему я стремлюсь, - это сделать (несколько) объективный случай, чтобы сказать что-то вроде: «За один год мы можем разработать X новых функций, если мы просто продолжим работу, но X + Y новые функции, если мы погасить часть этого технического долга ».
Эрик Дитрих
2

Там есть довольно сильная платформа под названием CASTискать технический долг в больших приложениях. Мы использовали его в проекте, где мы взяли на себя значительное усовершенствование устаревшей системы. Он не говорит вам, что было в голове у людей, которые написали код, но он анализирует код и находит недостатки кода и архитектуры, а затем количественно определяет технический долг, если хотите. Тем не менее, реальный смысл в этом - не сумма $, а список проблем, уже имеющихся в коде. Это говорит вам о той части технического долга, которая у вас есть (поэтому я не согласен с некоторыми ответами выше). Существует некоторый технический долг, который чисто дизайн на основе, и это очень субъективно - как порнография - вы знаете, когда вы видите его и знать контекст. Я бы сказал, действительно ли это «технический» долг. Существует некоторая техническая задолженность, которая заключается исключительно в реализации, и я считаю, что

Leonhard
источник
Я поделился этим вопросом в твиттере, и кто-то ответил, говоря о CAST. Мне не совсем понятно, что все это делает после проверки их веб-сайта. Есть ли какая-нибудь бесплатная или демоверсия, которую можно взять для тест-драйва?
Эрик Дитрих
2

Вот вебинар из Массачусетского технологического института, описывающий исследования технического долга в больших системах программного обеспечения: http://sdm.mit.edu/news/news_articles/webinar_050613/sturtevant-webinar-technical-debt.html

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

Работа, описанная в вебинаре, основана на исследовании модульности, проведенном Аланом МакКормаком и Карлиссом Болдуином в Гарвардской школе бизнеса. Я бы тоже посмотрел их документы. Их «стоимость распространения» может быть тем, что вы ищете.

user94203
источник
1

Я бы сказал, что стандартные метрики кода можно использовать как высокоуровневое относительное представление о технической задолженности. VS Ultimate включает в себя анализатор кода, который предоставит вам «Индекс ремонтопригодности» на основе цикломатической сложности, сцепления, LoC и глубины наследования. Вы можете погрузиться в любые проблемные места и увидеть детали (вплоть до уровня функций). Я только что запустил его в своем проекте, и самые низкие оценки мы получили 69 в нашем пакете данных (настройка и инициализация EF) и в нашем тестовом наборе. Все остальное было 90 или выше. Есть другие инструменты, которые дадут вам больше метрик, подобных тем, которые обсуждались в PPP дяди Боба.

Майкл Браун
источник
Итак, скажем, у вас было что-то не в тестовом наборе или пакете данных, которое было ниже 90. Есть ли у вас числовой порог там, где вы говорите: «Хорошо, этого недостаточно, и мы собираемся провести рефакторинг»? Или вы используете эту информацию, чтобы убедить руководство или какую-либо заинтересованную сторону в необходимости рефакторинга? То есть заботятся ли менеджеры / заинтересованные стороны об индексе ремонтопригодности Microsoft или вы предоставляете эту информацию другим способом? Или вы просто не представляете это и спокойно решаете проблему самостоятельно?
Эрик Дитрих
Мне нравится этот вопрос. Мой ответ всегда будет состоять в том, что написание лучшего кода, который вы можете, - это не то, о чем вы просите разрешения делать. Я использую то, что дядя Боб называет «правилом бойскаута» (всегда оставляю код в лучшем состоянии, чем когда вы приехали), и я называю оппортунистический рефакторинг. Идея состоит в том, что когда вам нужно изменить существующий код, найдите время, чтобы: а) охватить его в модульных тестах; б) реорганизовать его, чтобы он стал чище. Michael Feathers, эффективно работающий с Legacy Code, дает некоторые рекомендации по этому вопросу.
Майкл Браун
@ Mike - Это заставит вас работать во многих средах разработки, где жесткий контроль всех изменений кода отслеживается и контролируется. Особенно если ваше, казалось бы, невинное улучшение, которое никто не сказал вам исправлять, в конечном итоге сломало что-то, что когда-то работало.
Данк
Заметьте, я не говорил погружаться и волей-неволей очистить код. Я сказал, чтобы очистить код, над которым вы уже работаете. Я также работал с строго регламентированным кодом (получить назначенный рабочий элемент, предоставить список изменений, внесенных для утверждения рабочего элемента, выполнить утвержденные изменения). ). 9/10 раз объяснение рефакторинга в запросе на изменение приведет к утверждению.
Майкл Браун
0

Я бы не думал о техническом долге как о долларах, где для количественной оценки нужна модная модель. Я бы подумал об этом как об одолжении. Если кто-то делает вам одолжение, и вы, вероятно, забудете, запишите это. Когда вы берете короткий путь, запишите его. Это помогает вам вспомнить, и больше бессильно заставляет вас признать это. Не нужно никаких причудливых инструментов. Блокнот или Ecxel могут сделать свое дело.

MathAttack
источник
2
С точки зрения реальной политики, я бы сказал, что люди, которые больше всего хотят понести долгосрочные последствия для краткосрочных результатов, вероятно, также люди, которые менее всего склонны документировать свои решения. Итак, я согласен с вашей идеей в теории, но я думаю, что серийные «заказчики одолжений» с наименьшей вероятностью будут отслеживать баланс благосклонностей.
Эрик Дитрих
@ErikDietrich - я согласен. И худшие серийные преступники даже не знают, что они добавляют к своему долгу. (Подобно худшим нарушителям кредитных карт, сокрушающим свои кредитные рейтинги.) Но отправная точка предполагает стремление дать количественную оценку, и не писателю трудно дать количественную оценку. Вы не знаете, где корма, если это не ваша собака, или вы случайно не вмешались в нее.
MathAttack
0

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

о чем ты думаешь? Рад ответить на любые вопросы и с нетерпением жду ваших отзывов :).

Владение, чтобы предотвратить дефекты & нежелательный технический долг

Собственность является ведущим показателем инженерного здоровья.

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

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

Это несколько аналогично трагедии общего достояния .

Сплоченность для улучшения архитектуры

Сплоченность - это трейлинг-индикатор четко определенных компонентов.

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

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

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

Отток для выявления проблемных зон

Отток (повторяющаяся активность) помогает идентифицировать и ранжировать области, созревшие для рефакторинга в растущей системе.

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

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

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

Stefanie
источник
-1

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

Эрик Реппен
источник