Como quantificar o montante da dívida técnica existente em um projeto?


67

Alguém sabe se existe algum tipo de ferramenta para colocar um número em dívida técnica de uma base de código, como uma espécie de métrica de código? Caso contrário, alguém conhece um algoritmo ou conjunto de heurísticas para ele?

Se nenhuma dessas coisas existir até agora, eu estaria interessado em idéias sobre como começar com uma coisa dessas. Ou seja, como posso quantificar a dívida técnica incorrida por um método, uma classe, um espaço para nome, um assembly etc.

Estou mais interessado em analisar e avaliar uma base de código em C #, mas sinta-se à vontade para entrar em contato com outros idiomas também, principalmente se os conceitos forem transcendentes.


12
A dívida técnica vem de decisões, não de código. É acumulado devido a más escolhas de gerenciamento. Não está claro que "método, classe, espaço para nome, assembléia" contenham dívidas técnicas por si mesmas. Eles representam um passivo quando há uma opção melhor disponível.
315 S.Lott

7
Eu argumentaria (no contexto da metáfora da dívida) que os gerentes podem ser os detentores da dívida, mas os artefatos de código representam a avaliação da dívida e podem ser quantificados. Ou seja, concordo que os gerentes podem tomar uma decisão como "esqueça o teste de unidade porque não temos tempo" e, portanto, incorrem em dívida técnica. Mas, certamente, acho que você pode colocar um número em elementos de código individuais como uma heurística. Pense desta maneira - se a gerência tomar uma série de decisões horríveis para o futuro, mas nenhum código foi escrito, existe alguma dívida naquele momento?
Erik Dietrich

3
"existe alguma dívida naquele momento?" A dívida precisa acumular, você está certo. Mas não é o código; é o volume de "trabalho" realizado que precisa ser desfeito. Especificações, projetos, código, trabalho DBA, tudo isso precisa ser reformulado. A medição da dívida de artefatos de software (como linhas de código fonte) é semelhante à previsão do custo de desenvolvimento.
31512 S.Lott

7
Medir a dívida técnica é difícil, além de confundir os gerentes. No entanto, posso lhe dizer uma boa maneira de combater a dívida técnica: protótipos baratos, agradáveis ​​e funcionais, especialmente se a base de código gira em torno da GUI. Como Joel sugeriu aqui: joelonsoftware.com/articles/fog0000000332.html , gaste um pouco de tempo todos os dias limpando as coisas. A mudança deve ser uma melhoria positiva, não "OMG, nossa dívida técnica = pentablobs e está aumentando exponencialmente a uma taxa de ... o céu está caindo". Apenas gaste um pouco de tempo todos os dias no Kaizen de uma maneira que não quebre as coisas que funcionam. Fazer amigos.
Job

6
@ZoranPavlovic Seu falso dilema bizarro e não solicitado está faltando uma terceira opção: eu queria saber se havia alguma ferramenta que tentasse quantificar a dívida técnica.
Erik Dietrich

Respostas:


38

Dívida técnica é apenas uma idéia abstrata de que, em algum ponto da linha de projeto, construção, teste e manutenção de um sistema, foram tomadas determinadas decisões para que o produto se torne mais difícil de testar e manter. Ter mais dívida técnica significa que será mais difícil continuar desenvolvendo um sistema - você precisa lidar com a dívida técnica e alocar cada vez mais tempo para o que de outra forma seriam tarefas simples ou investir recursos (tempo e tempo). dinheiro) na redução da dívida técnica, refatorando o código, aprimorando os testes e assim por diante.

Existem várias métricas que podem fornecer algumas indicações sobre a qualidade do código:

  • Cobertura de código. Existem várias ferramentas que informam qual porcentagem de suas funções, instruções e linhas são cobertas por testes de unidade. Você também pode mapear os testes de sistema e aceitação de volta aos requisitos para determinar a porcentagem de requisitos cobertos por um teste no nível do sistema. A cobertura apropriada depende da natureza do aplicativo.
  • Acoplamento e coesão . Código que exibe baixo acoplamento e alta coesão é geralmente mais fácil de ler, entender e testar. Existem ferramentas de análise de código que podem relatar a quantidade de acoplamento e coesão em um determinado sistema.
  • Complexidade ciclomática é o número de caminhos exclusivos através de um aplicativo. Geralmente é contado no nível do método / função. A complexidade ciclomática está relacionada à compreensibilidade e testabilidade de um módulo. Não apenas os valores de complexidade ciclomática mais altos indicam que alguém terá mais problemas ao seguir o código, mas a complexidade ciclomática também indica o número de casos de teste necessários para obter cobertura.
  • As várias medidas de complexidade de Halstead fornecem informações sobre a legibilidade do código. Eles contam os operadores e operandos para determinar o volume, a dificuldade e o esforço. Muitas vezes, isso pode indicar o quão difícil será para alguém pegar o código e entendê-lo, geralmente em casos como uma revisão de código ou um novo desenvolvedor na base de código.
  • Quantidade de código duplicado. Código duplicado pode indicar potencial para refatoração de métodos. Ter código duplicado significa que há mais linhas para a introdução de um bug e maior probabilidade de os mesmos defeitos existirem em vários locais. Se a mesma lógica comercial existir em vários locais, fica mais difícil atualizar o sistema para levar em conta as alterações.

Muitas vezes, as ferramentas de análise estática poderão alertá-lo sobre possíveis problemas. Obviamente, apenas porque uma ferramenta indica um problema não significa que há um problema - é preciso julgamento humano para determinar se algo pode ser problemático no futuro. Essas métricas apenas fornecem avisos de que talvez seja hora de examinar um sistema ou módulo mais de perto.

No entanto, esses atributos se concentram no código. Eles não indicam prontamente qualquer dívida técnica na arquitetura ou no design do sistema que possa estar relacionada a vários atributos de qualidade.


11
Atualmente, uso as métricas de código NDepend ( ndepend.com ), CodeRush e VS para ficar de olho nas métricas mencionadas (com exceção das medidas de Halstead, as quais analisarei mais adiante). Eu estava pensando que poderia usar alguma amálgama dessas métricas para tentar colocar algum tipo de número em um determinado elemento de código que indicaria aproximadamente, de relance, o quanto custou o desenvolvimento contínuo.
Erik Dietrich

@ErikDietrich Você pode, mas eu provavelmente não quantificaria esse valor. Talvez um relatório de estilo "resumo executivo" sobre o que suas ferramentas de métricas dizem a você, com relação às mudanças ao longo do tempo, seja mais apropriado.
Thomas Owens

2
Outra métrica simples que eu adicionaria à lista é o número de TODO / HACK / WTF? comentários em uma base de código ...
MaR

@Mar Isso pressupõe que você os use corretamente e não os jogue para sua vantagem. Quer um tempo extra para limpar a base de código, basta adicionar esses comentários onde não forem apropriados. Não se preocupe com a base de código, apenas remova-a de onde deveria estar. Os comentários podem mentir, o código não.
Thomas Owens

11
@ Thomas Owens: concordou, mas quase qualquer métrica sozinha pode ser enganada. Se usada corretamente e honestamente, a "métrica TODO" fornece uma visão geral barata de qual código está realmente ausente ou deve ser alterado (= dívida invisível para métricas baseadas em código).
21412 MaR

23

O sonar possui uma heurística de dívida técnica, além de vários outros recursos úteis para um projeto de software.

Ele também suporta uma ampla variedade de idiomas.

O SonarQube (anteriormente Sonar ) é uma plataforma de código aberto para Inspeção Contínua da qualidade do código ...

  • Suporta mais de 25 idiomas: Java, C / C ++, C #, PHP, Flex, Groovy, JavaScript, Python, PL / SQL, COBOL, etc.
  • O SonarQube também é usado no Android Deveopment.
  • Oferece relatórios sobre código duplicado, padrões de codificação, testes de unidade, cobertura de código, código complexo, possíveis bugs, comentários e design e arquitetura.
  • Máquina do tempo e vistas diferenciais.
  • Análises totalmente automatizadas: integram-se às ferramentas Maven, Ant, Gradle e de integração contínua (Atlassian Bamboo, Jenkins, Hudson, etc.).
  • Integra-se ao ambiente de desenvolvimento Eclipse
  • Integra-se com ferramentas externas: JIRA, Mantis, LDAP, Fortify, etc.
  • Expansível com o uso de plugins.
  • Implementa a metodologia SQALE para calcular dívida técnica ...

11
Legal, obrigado! Eu tenho e uso o NDepend para o meu trabalho em C #, mas também trabalho um pouco em Java e também estou interessado em métricas. No mínimo, isso me dá funcionalidade para Java e pode ser um bom complemento para o NDepend.
Erik Dietrich

Incrível, usamos o Sonar onde eu trabalho e ele faz algumas coisas realmente boas que fornecem uma visão do estado da sua base de código.
Robert Greiner

2
@ErikDietrich, o FYI Sonar também tem um plugin C # .
Péter Török

@ErikDietrich FYI agora existe um plugin NDepend para o sonar ndepend.com/docs/sonarqube-integration-ndepend
Patrick Smacchia - NDepend dev

Existem alternativas de código aberto?
Hellboy

5

Eu odeio usar uma analogia das finanças, mas parece realmente apropriado. Quando você está precificando algo (ativos de qualquer tipo), ele pode ter valor intrínseco e extrínseco. Nesse caso, o código existente tem valor intrínseco que seria uma quantidade correspondente à qualidade relativa do referido código e também teria valor extrínseco (valor do que poderia ser feito com o código) e essas quantidades seriam aditivas. O valor intrínseco pode ser dividido em créditos e débitos (bom versus ruim) usando qualquer metodologia que você esteja usando para pontuar o código (+5 para comentários / legibilidade, -10 para cobertura de código etc.)

Certamente não conheço nenhuma ferramenta que quantifique isso hoje e acho que você teria uma discussão inteiramente nova em suas mãos se argumentar sobre o mérito de diferentes estratégias de "avaliação da dívida", mas eu concordo com Matthew - a dívida é a custo cumulativo de obter o código da melhor maneira possível, usando qualquer método usado para custar as horas de trabalho necessárias para chegar lá.

Outra coisa a considerar é que certamente existe uma medida de custo-benefício em que, à medida que nos aproximamos da "perfeição", o valor de uma hora gasta na base de código está mais do que provavelmente diminuindo exponencialmente, de modo que provavelmente há um problema adicional de otimização. maximizar a utilidade do trabalho realizado.


Sim, o conceito de diminuição dos retornos marginais é certamente algo que eu gostaria de abordar ao elaborar e refinar a métrica. Portanto, não apenas "aqui está o meu argumento objetivo para refatorar essa classe de uma perspectiva de negócios", mas também "aqui está a minha justificativa para não me incomodar neste momento".
Erik Dietrich

5

Entre os desenvolvedores, uma medida razoavelmente confiável da dívida técnica parece ser WTFs / minuto .

O problema com essa "métrica" ​​é que normalmente é bastante difícil se comunicar "fora".

A métrica que funcionou para mim na comunicação da dívida técnica para "pessoas de fora" foi a quantidade de esforço de teste e correção de bugs (especialmente para corrigir bugs de regressão ) necessários para uma entrega bem-sucedida.

Uma palavra de cautela: embora essa abordagem seja bastante poderosa, é melhor verificar novamente com bons WTFs antigos / minuto antes de recorrer a ela. O fato é que é bastante complicado: para obter os dados, é preciso rastrear cuidadosamente o tempo e registrá-lo com precisão pelas categorias apropriadas.

  • é muito mais fácil declarar 3 semanas no total gasto na implementação do recurso A do que
     
    eu passei 14 horas no rascunho da implementação do recurso A, depois 29 horas no teste de fumaça e 11 horas na implementação de correções para regressões que descobri, depois de 18 horas testando o controle de qualidade implementação de recursos já. Depois disso, os funcionários do controle de qualidade passaram 17 horas testando o release inicial do candidato. Depois disso, passei 13 horas analisando os bugs enviados pelo controle de qualidade para a liberação inicial do candidato e 3 horas implementando as correções. Depois disso, passei 11 horas testando as alterações que fiz na liberação inicial do candidato. Depois disso...

De qualquer forma, os dados sobre o esforço de teste e correção de bugs foram bastante fáceis de se comunicar na minha experiência.

Para uma versão recente, gastamos cerca de 90% do tempo testando e corrigindo erros de regressão. Para a próxima versão, sugira alocar algum esforço para reduzir esse valor para 60-70%.


Outra palavra de cautela. Dados como 90% acima podem ser interpretados não apenas como uma indicação de dívida técnica, mas também (surpresa surpresa) como uma indicação de que alguém não é muito proficiente em programação / tecnologia específica. "Você apenas comete muitos erros no seu código".

Se houver o risco de os dados serem mal interpretados dessa maneira, ajudará a ter dados de referência adicionais sobre algo menos propenso a WTF para comparação.

  • Digamos que, se houver dois componentes / aplicativos semelhantes mantidos pelo (s) mesmo (s) desenvolvedor (es), lançando primeiro a uma "taxa de desperdício" em cerca de 50% e depois em 80-90, isso é um argumento bastante forte a favor de o segundo ser objeto de dívida técnica.

Se houver testadores dedicados no projeto, eles também poderão contribuir para uma avaliação mais objetiva dos dados. Como mencionei em outra resposta ,

Com os testadores, você recebe alguém para fazer backup de sua compreensão dos problemas de design. Quando há apenas desenvolvedores reclamando da qualidade do código , isso geralmente soa como WTFs subjetivos por trás da porta fechada .
 
Mas quando isso é repetido pelo cara do controle de qualidade dizendo que algo como component A100 bugs de regressão para 10 novos recursos, em vez de component B10 bugs de regressão para 20 novos recursos , a comunicação de repente se transforma em outro jogo.


2
Eu gosto muito dessa resposta. Com um departamento de controle de qualidade dedicado, a taxa de defeitos de regressão para novos defeitos é muito simples de calcular e definitivamente pode lhe dizer muito sobre dívida técnica.
Erik Dietrich

4

Acho que a pergunta é quanto custaria "recomprar" sua dívida técnica - ou seja, quanto trabalho é necessário para corrigi-la? Bem, cabe à equipe descobrir isso.

Durante o planejamento do sprint, peço à equipe que estime a complexidade de corrigir itens de dívida técnica da mesma maneira que estimaria a complexidade de uma história de usuário. Nesse ponto, é um jogo de negociação entre a equipe e o proprietário do produto para determinar qual dívida técnica é alta o suficiente para ser feita no sprint atual (substituindo as histórias reais do usuário) e o que pode esperar.

Se você não está fazendo scrum, eu me ateria à minha premissa - a dívida técnica deve ser medida pelo custo do remédio.


Portanto, no contexto dos pontos da história, é justo dizer que você poderia adicionar alguns pontos a cada história se houvesse um alto grau de dívida técnica representada pelas áreas afetadas do código? Ou seja, se a história X envolve adicionar ao elemento de código Y, o que é simplesmente horrível, você adere alguns pontos à história especificamente por causa da natureza de Y? E esse número de pontos é igual ou relacionado ao número de pontos para executar a correção que você mencionou estimar?
Erik Dietrich

11
@Erik Dietrich - Bem, o TD está definitivamente adicionando complexidade à solução. A dificuldade pode ser que fixar o TD em partes pode ser mais caro do que uma solução de atacado. Portanto, pode ser que você tenha 3 histórias que seriam classificadas em 5 cada, se o TD fosse eliminado, mas são 8 cada uma com a dívida em vigor - de modo que soma 9 pontos de TD. A tarefa de corrigir o DT como um todo (independentemente das histórias) pode ser realmente um 8. Portanto, você pode argumentar que a solução de atacado custa menos (8) do que a fragmentada (9). Isso seria parte da negociação
Matthew Flynn

Isso faz sentido. E, certamente, o que pretendo chegar é apresentar um caso (um tanto) objetivo para dizer algo como "em um ano, podemos desenvolver X novos recursos se continuarmos avançando, mas X + Y novos recursos se pagar parte dessa dívida técnica ".
Erik Dietrich

2

Existe uma plataforma bastante forte chamada CASTprocurar dívida técnica em grandes aplicações. Nós o usamos em um projeto em que assumimos uma grande melhoria em um sistema legado. Ele não informa o que estava na cabeça das pessoas que escreveram o código, mas examina o código e encontra falhas de código e arquitetura, depois quantifica a dívida técnica, se você quiser. O uso real de analisar isso, no entanto, não é o valor de $, mas a lista de problemas já existentes no código. Isso informa sobre uma parte da dívida técnica que você possui (então eu discordo de algumas das respostas acima). Existe alguma dívida técnica puramente baseada em design e muito subjetiva - como a pornografia - você a conhece quando a vê e conhece o contexto. Eu argumentaria se isso é realmente uma dívida "técnica". Existe alguma dívida técnica puramente na implementação e acredito que '


Compartilhei essa pergunta no twitter e alguém respondeu falando sobre o CAST. Eu não sou muito claro sobre o que tudo isso faz depois de verificar o site deles. Existe algum brinde ou versão demo dele para um test drive, por acaso?
Erik Dietrich

2

Aqui está um seminário on-line do MIT que descreve a pesquisa sobre dívida técnica em grandes sistemas de software: http://sdm.mit.edu/news/news_articles/webinar_050613/sturtevant-webinar-technical-debt.html

Os autores escreveram código para analisar um projeto e extrair métricas de 'complexidade arquitetônica'. Essas métricas mostraram ter um forte relacionamento com a densidade de defeitos, a produtividade do desenvolvedor e a rotatividade da equipe de desenvolvimento.

O trabalho descrito no Webinar baseia-se na pesquisa de modularidade realizada por Alan MacCormack e Carliss Baldwin na Harvard Business School. Gostaria de olhar para os papéis deles também. O 'custo de propagação' deles pode ser o que você está procurando.


1

Eu diria que as métricas de código padrão podem ser usadas como uma visão relativa de alto nível do endividamento técnico. O VS Ultimate inclui um analisador de código que fornece um "Índice de Manutenção" com base na complexidade ciclomática, acoplamento, LoC e profundidade de herança. Você pode mergulhar em qualquer ponto problemático e ver detalhes (até o nível da função). Acabei de executá-lo no meu projeto e as pontuações mais baixas que obtivemos foram 69 em nosso pacote de dados (configurando e inicializando o EF) e em nosso conjunto de testes. Todo o resto tinha 90 anos ou mais. Existem outras ferramentas que fornecerão mais métricas, como as discutidas no PPP do tio Bob.


Então, diga que você tinha algo que não estava no conjunto de testes ou no pacote de dados com pontuação abaixo de 90. Você tem um limite numérico no local em que diz "tudo bem, isso não é bom o suficiente e vamos refatorar"? Ou você usa essas informações para defender a gerência ou alguma parte interessada de que é necessária uma refatoração? Ou seja, os gerentes / partes interessadas se preocupam com o índice de manutenção da Microsoft ou você apresenta essas informações de alguma outra maneira? Ou você simplesmente não a apresenta e corrige o problema silenciosamente por conta própria?
Erik Dietrich

Eu amo essa pergunta. Minha resposta será sempre que escrever o melhor código possível não é algo que você pede permissão para fazer. Uso o que o tio Bob chama de "regra do escoteiro" (sempre deixe o código em melhores condições do que quando você chegou) e chamo de refatoração oportunista. A idéia é que, quando você precisar modificar o código existente, reserve um tempo para: a) cobri-lo em testes de unidade; b) refatorá-lo para que fique mais limpo. Michael Feathers Trabalhando efetivamente com o Legacy Code fornece algumas orientações sobre como fazer isso.
Michael Brown

@ Mike - Isso fará com que você seja demitido em muitos ambientes de desenvolvimento em que o controle rígido de todas as alterações de código é rastreado e monitorado. Especialmente se sua melhoria aparentemente inocente que ninguém lhe pediu para corrigir acabasse quebrando algo que antes funcionava.
Dunk

Note que eu não disse que mergulhe e limpe o código. Eu disse para limpar o código em que você já está trabalhando. Também trabalhei com código altamente regulamentado (receba um item de trabalho, é necessário fornecer uma lista de alterações que estão sendo feitas para abordar o item de trabalho para aprovação, executar alterações aprovadas ) 9/10 vezes a explicação da refatoração na solicitação de mudança resultaria em aprovação.
Michael Brown

0

Eu não pensaria em dívida técnica como dólares, onde você precisa de um modelo sofisticado para quantificá-la. Eu pensaria nisso como favores. Se alguém lhe faz um favor e é provável que você esqueça, anote. Quando você toma um atalho, anote-o. Isso ajuda você a se lembrar, e mais impotentes o obrigam a reconhecê-lo. Nenhuma ferramenta sofisticada é necessária. O bloco de notas ou Ecxel podem fazer o truque.


2
Do ponto de vista da política real, eu argumentaria que as pessoas mais dispostas a sofrer maldades a longo prazo por resultados de curto prazo provavelmente também são as menos propensas a documentar suas decisões. Então, eu concordo com sua idéia na teoria, mas acho que os "solicitantes de favor" em série seriam os menos propensos a acompanhar o balanço de favores.
Erik Dietrich

@ErikDietrich - eu concordo. E os piores criminosos em série nem sabem que estão aumentando sua dívida. (Semelhante aos piores infratores de cartão de crédito que esmagam suas classificações de crédito.) Mas o ponto de partida pressupõe o desejo de quantificar, e é difícil para o não-escritor quantificá-lo. Você não sabe onde está o cocô, a menos que seja o seu cachorro, ou por acaso ele entrou.
MathAttack

0

Eu trabalho para uma empresa que está investigando exatamente isso. Abaixo estão três métricas acionáveis ​​que recomendamos analisar ao lidar com dívidas técnicas. Para mais informações sobre "como" e "quando" para rastreá-los, reunimos um artigo de resumo 3 Métricas para Entender e Combater a Dívida Técnica .

Quais são seus pensamentos? Fico feliz em responder a quaisquer perguntas e com fome de ouvir o seu feedback :).

Propriedade para evitar defeitos e dívida tecnológica indesejada

A propriedade é um indicador importante da saúde da engenharia.

As partes da base de código que recebem contribuições de muitas pessoas acumulam lixo ao longo do tempo, enquanto as que recebem contribuições de menos pessoas tendem a estar em um estado melhor. É mais fácil manter altos padrões em um grupo restrito e bem informado sobre sua parte da base de código.

Isso fornece algum poder preditivo: partes fracas da base de código provavelmente acumularão dívidas ao longo do tempo e se tornarão cada vez mais difíceis de trabalhar. Em particular, é provável que a dívida seja assumida involuntariamente , simplesmente como efeito colateral de informações incompletas e propriedade diluída da qualidade do código.

Isso é um tanto análogo à tragédia dos bens comuns .

Coesão para melhorar a arquitetura

A coesão é um indicador final de componentes bem definidos.

A coesão e sua contraparte, o acoplamento, são há muito reconhecidas como conceitos importantes a serem focados ao projetar software.

Diz-se que o código tem alta coesão quando a maioria de seus elementos se une. A alta coesão é geralmente preferível porque está associada à capacidade de manutenção, reutilização e robustez. Coesão alta e acoplamento frouxo tendem a andar de mãos dadas.

Além de ser associada a um código mais reutilizável e sustentável, a alta coesão também minimiza o número de pessoas que precisam se envolver para modificar uma determinada parte da base de código que aumenta a produtividade.

Rotação para identificar áreas problemáticas

A rotatividade (atividade repetida) ajuda a identificar e classificar áreas prontas para refatoração em um sistema crescente.

À medida que os sistemas crescem, fica mais difícil para os desenvolvedores entender sua arquitetura. Se os desenvolvedores tiverem que modificar muitas partes da base de código para fornecer um novo recurso, será difícil para eles evitar a introdução de efeitos colaterais que causam bugs, e serão menos produtivos porque precisam se familiarizar com mais elementos e conceitos.

É por isso que é importante lutar pela responsabilidade única de criar um sistema mais estável e evitar consequências não intencionais. Enquanto alguns arquivos são hubs de arquitetura e permanecem ativos à medida que novos recursos são adicionados, é uma boa idéia escrever código de maneira a fechar os arquivos e revisar rigorosamente, testar e controlar as áreas de agitação de controle de qualidade.

O Churn apresenta esses arquivos ativos para que você possa decidir se eles devem ser divididos para reduzir a área de mudança da superfície da sua base de código.


-1

Se você tem um bom histórico através de um rastreador de bugs ou algum tipo de software ágil, pode mantê-lo simples. Tempo gasto na conclusão de tarefas básicas. Além disso, confiabilidade das estimativas quando o projeto era jovem versus agora.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.