Débito Técnico: por que isso vai estragar teu software
Como você pode ver, esse é um monumento super conhecido que fica na Itália, mais especificamente em Pisa por isso o nome: Torre de Pisa.
Essa torre tem uma história super interessante, ela foi construída no século 12 e, por motivos de o solo não ter sustentação suficiente para aguentar seu peso, ela começou a tombar. A estrutura foi então estabilizada só em 2001 após 8 anos de "retrabalho".
Na verdade, uma das correções feita durante o retrabalho tornou inclinação ainda pior! Assim né, quem aqui nunca fez uma refatoração que na real tornou o problema pior, né? Eu não posso culpar eles haha
Chico, the purrgrammer
- Esse é Chico.
- Chico é um Desenvolvegato Senior sempre com horrores de coisas para fazer
- Chico também é um programador incrível com anos e anos de experiência
De repente um novo projeto apareceu para Chico, e esse novo projeto precisava ter:
- Sistema de Pagamento
- Autenticação por Redes Sociais
- Integração com serviços de Entrega
A data de entrega para esse projeto é de apenas: Um Mês.
Como Chico é um excelente profissional que sempre entrega as suas atividades, ele foi lá, pegou o novo projeto e o entregou a tempo.
Depois de entregue, o resto do time foi revisar o código de Chico, e eles descobriram que ele tinha alguns problemas, como:
- Bugs e inconsistência nos pagamentos
- Algumas vezes as entregas não eram processadas
- Autenticação era muito leiga ao checar as redes sociais utilizadas
Chico sabia que seu código tinha alguns bugs. Porém quando Chico estava perto da data de entrega outro projeto apareceu para ele e então ele não teve tempo de voltar pra corrigir esses problemas.
Eles tiveram que entregar o projeto do jeito que ele estava.
Mas Chico se manteve positivo!
SPOILER
Ah, gente, claro que isso não iria acontecer, né?
Vamos entender mais a fundo quais eram os reais problemas do código:
- Pagamentos não aceitam diferentes moedas
- Se o serviço de entregas estiver fora do ar, o código para de funcionar
- Usuários com contas desativadas ainda conseguem acessar o sistema
- Sem testes automatizados
E é isso que conhecemos por Débito Técnico. Por que?
Porque, como Chico escolheu a primeira alternativa de solução que ele pensou, por conta da data de entrega, a qualidade do código foi afetada, e o time aceitou isso. No futuro, se qualquer parte da regra de negócio precisar ser alterada, como aceitar outros tipos de moedas ou se quisermos mudar o serviço de entregas, o Custo da Mudança no código de Chico vai ser muito maior. Esse foi o momento que o Débito Técnico foi inserido.
O que aconteceu na Torre de Pisa é bem parecido com que entendemos por Débito Técnico.
Tudo provavelmente começou com alguns erros e problemas, mas a construtora decidiu ignorá-los e continuou aumentando a obra em cima desses problemas. A torre foi erguida tão rapidamente que esses pequenos “bugs” na construção acabaram comprometendo toda a estrutura.
E o mesmo acontecer com softwares. A diferença é que esses bugs são mais visíveis durante o processo de desenvolvimento, porque, depois de algum tempo, tudo começa a ser mais difícil de entregar até que os bugs sejam resolvidos.
Por que Débito Técnico é sempre algo ruim?
Nós estamos acostumados a pensar que ter qualquer nível de Débito no nosso software é sempre uma coisa muito ruim. E, assim, geralmente é.
Mas podemos também enxergá-lo como uma decisão estratégica. Uma funcionalidade entregue com Débito Técnico ainda é uma funcionalidade que foi entregue rapidamente. E isso pode trazer muito valor para o produto.
O problema dessa abordagem começa quando esquecemos o que fizemos no passado. Imagine que Débito Técnico é tipo comer um podrão no meio da rua. Um ou dois é massa, porém, depois do oitavo ou nono, pode ser que você tenha um problema, né?
Aceitando esse débito como um tradeoff, nós podemos nos mover mais rápido e pagar as consequências pelas nossas decisões no futuro. E isso é realmente uma coisa muito comum de se fazer.
Eu não sei quantas pessoas aqui já pagaram o preço de comer muitos podrões. Mas lembrem-se que o custo disso, assim como no software, aumenta com o tempo.
Então, se você se identificou com alguma dessas situações nas suas tarefas do dia a dia, tudo bem, principalmente se você tiver um tempo dedicado, no futuro, para remediar esse problema. Isso é realmente um cenário super comum ao entregar software.
Quadrante de Débito Técnico
Se olharmos para o Quadrante de Débito Técnico de Martin Fowler podemos facilmente identificar que Chico está na parte de cima, entre ser Desleixado e Prudente.
Ele sabe que não tinha tanto tempo para desenhar a melhor solução mas também tinha claro para ele que: No futuro ele precisará voltar e melhorar o seu código.
Massa, aceitando que isso é algo corriqueiro, podemos partir para entender quem realmente são as pessoas responsáveis pelo débito de um software.
Quem é responsável pelo Débito?
Se pensarmos apenas no nome (Débito Técnico), somos levados a pensar que isso é um problema do time de pessoas técnicas, ou seja, de pessoas desenvolvedoras, que foram responsáveis por escrever o código que causou tudo isso.
O problema é que um software é o resultado da estrutura e dos processos da empresa inteira.
Também é importante lembrar que a indústria inteira de software mudou demais desde o tempo que o termo Débito Técnico nasceu. Assim como no cenário de Chico, o problema da solução não-tão-boa que ele escreveu está mais ligado a um problema de Gestão ou do time de Produto do que apenas dele. Porque sabemos que Chico é um bom desenvolvegato, mas ele precisou ignorar os problemas para poder entregar o projeto na data que lhe foi pedida.
Algumas vezes os gargalos que estão gerando débito vêm de diferentes partes da sua empresa, como:
- Time de Gerência vs Velocidade do Time de Desenvolvimento
- Time de Produto pode não ter um plano a longo prazo
- Time de UI/UX pode estar muito distante das pessoas desenvolvedoras
E também não podemos esquecer que às vezes nós precisamos nos culpar pelas má decisões.
- Nossas má-decisões contam
- Sintomas de Frameworks
- Baixa cobertura de testes
Tipo, quando escolhemos um framework apenas por puro hype, não investimos um tempo para garantir que aquela é realmente a melhor ferramenta, ou quando paramos de dar atenção aos sinais de um framework sendo abandonado, ou até se as pessoas desenvolvedoras não estão testando e refatorando a aplicação como ela merece ser… Tudo isso é nossa responsabilidade.
Depois de descobrimos quais problemas nós temos em nosso código, precisamos ver quais as possíveis ferramentas podem nos ajudar a lidar com essas situações.
Como lidar com isso?
- Reescrever tudo?
- Contratar mais pessoas para lidar apenas com o Débito?
- Parar tudo até que os pontos de alto débito estejam corrigidos?
- Criar tarefas para de débito técnico em uma quadro separado apenas para Débito Técnico?
Imagine se as pessoas tivessem parado de trabalhar na Torre de Pisa e destruído tudo para reconstruir. A chance de que os mesmo problemas ou até novos aparecem na torre é realmente grande, sem pensar nem na quantidade de dinheiro gasto para demolir e reconstruir tudo.
Se a empresa apenas contratasse mais pessoas, imagine no caso da Torre. Nós estamos só adiando o problema por ter pessoas trabalhando em puxar a Torre do outro lado para mantê-la reta, isso realmente não resolve o problema principal.
Nos nossos projetos de software, se adicionássemos mais pessoas o time teria agora que além de lidar com todos os problemas existentes precisaríamos também explicar todo o contexto do software para o novo time, isso consome mais tempo do que se imagina.
Imagina se nós criarmos um novo lugar para guardar os problemas de Débito Técnico, depois de um tempo ele vai se tornar totalmente invisível para o time.
Se em um backlog normal de desenvolvimento já tem suas tarefas mais antigas invisíveis para o time, imagina um separado? No entanto, essas são as soluções que a maioria das pessoas buscam.
Luan, se essas opções não são as mais viáveis, o que podemos fazer?
Com base em tudo que vemos, vamos tentar encontrar soluções realmente viáveis para lidar com Débito Técnico.
Soluções sustentáveis
1. I.M.P.A.C.T
O IMPACT é um processo de:
- Identificar
- Marcar
- Planejar
- Agir
- Testar
Como podemos ver, o primeiro passo é sobre encontrar os pontos de débito e, no segundo passo, precisamos ter certeza que esses pontos estão visíveis para todo o time. Podemos fazer isso através da criação tarefas marcadas como Débito Técnico, por exemplo. E nós também podemos escolher prioridades nessas tarefas baseados na relevância. Ferramentas como o Jira têm mecanismos para aumentar essa prioridade de acordo com o tempo, o que é incrível pois, como vimos anteriormente, o custo do débito técnico também aumenta ao longo o tempo.
Baseados nas tarefas marcadas, precisamos planejar e seguir esse plano. Desta forma, iremos efetivamente Agir nos débitos e, após as correções e melhorias serem implementadas, precisamos Testar e garantir que nenhum comportamento foi prejudicado, independentemente dele ser um novo cenário de bug, uma feature, uma melhoria ou qualquer outra coisa que possa atrapalhar a experiência final.
Você pode encontrar informações mais detalhadas no livro "Refactoring for Software Design Smells Managing Technical Debt".
2. Princípio de Pareto
Para caso você não saiba quantas tarefas deve ter a cada iteração do time.
Nós podemos usar o princípio de Pareto, no qual 20% da produtividade do time é destinada para as tarefas de débito e o resto dos 80% pode ser usado para tarefas normais como novos recursos, correção de bugs e tudo mais.
3. Reuniões de Revisão de Débito Técnico
Se o seu processo tiver grandes lançamentos após algumas iterações, uma boa prática é agendar reuniões de post-mortem para discutir tudo que foi introduzido no nosso código e que tenha potencial para aumentar nossa dívida técnica.
Ao fazer isso, poderemos identificar esses débitos mais cedo.
Esses são três exemplos simples de soluções possíveis, mas eu recomendo que você seja crítico e crítica sobre tudo isso e decida o que melhor combina com você e seu time.
Vamos nos aprofundar em uma visão econômica sobre o custo de trabalhar e lidar com um sistema que já tenha valor considerável de débito técnico?
É lucrativo?
Para este ponto, vou usar uma palestra de J.B. Rainsberger. Nela, Rainsberger explica o custo do próximo novo recurso do seu software e como você pode diminuir a incerteza de calcular esse custo.
Nesse gráfico ele faz uma comparação dos dois custos ao longo do tempo do projeto.
Como podemos ver o crescimento do custo em um software feito sem pensar em design, refatoração e boas práticas cresce muito mais rápido do que se tivesse começado seu software pensando em design.
Apesar de que a proposta de se começar pensando em design de arquitetura e tudo mais tenha um custo bem mais alto no início, podemos ver que esse custo é mitigado ao longo do tempo se comparado com a outra abordagem.
Ao longo do tempo o custo do próximo recurso sem se pensar em design se torna tão grande que se a gente parasse tudo e fosse refazer tudo do zero valeria mais a pena.
Se você atualmente está escrevendo seu software dessa forma, você está apostando que o projeto vai acabar antes da linha pontilhada chegar.
E a parte mais difícil disso tudo é que nós não temos idéia de quando esse momento vai chegar, ele pode ser em 3 meses, um ano, 10 anos… Nós não sabemos.
Softwares de baixa qualidade tornou-se um dos tópicos mais caros da história da humanidade.
No ano passado, o CISQ divulgou um relatório sobre os custos de software nos EUA, o cálculo levou em consideração: Sistemas legados, falhas catastróficas e o custo de projetos problemáticos e cancelados. Apenas para a gente ter uma noção, esse valor corresponde a 2/3 do total de despesas com saúde nos EUA no mesmo ano.
Além do Lucro
Além do gasto excessivo de dinheiro e das entregas mais lentas existem várias outros problemas que podemos identificar que são causados apenas por trabalhar com um nível alto de débito.
O débito técnico traz muito peso às nossas vidas. Se você está constantemente lidando com códigos problemáticos, uma tarefa que parece fácil de se concluir pode se transformar em um verdadeiro monstro.
Ansiedade e Depressão
É comum ter receios em fazer mudanças, ainda mais se você é novo no projeto. As reuniões de planejamento podem se tornar intermináveis uma vez que a equipe de desenvolvimento precisa discutir com a equipe de gerência do projeto para explicar o quão difícil é entregar as novas coisas agora.
Começamos a ficar ansiosos porque não sabemos se algo vai surgir com o tempo, algum grande problema ou um bug difícil de se encontrar no meio de uma sprint.
Quem aqui nunca teve ou ainda tem algum código com algo desatualizado ou não mantido mais?
Atrofia das habilidades técnicas
É um cenário comum para pessoas desenvolvedoras. E é bem complicado de se lidar, porque nós precisamos aceitar todas as consequências e os problemas que vêm com isso.
Geralmente o que acontece é que você começa a copiar e colar código de uma biblioteca ou framework desatualizado e a corrigir os problemas você mesmo. Ou até, às vezes, você só faz uma cópia do projeto e começa a usar o seu clone.
Além disso nós podemos encontrar algumas incompatibilidades com ferramentas novas. Algumas plataformas que você deseja utilizar, mas não pode pois está preso a alguma versão antiga ou a uma ferramenta que não é mais suportada por essas plataformas.
Imagine só como deve ser difícil pra alguma pessoa desenvolvedora ser realocada no mercado de trabalho depois de passar cinco anos em um framework javascript que não é mais mantido e então precisa mudar para trabalhar com React ou Vue.js por exemplo.
Muitos conceitos que nós já estamos acostumados a trabalhar podem nem existir numa ferramenta velha.
Crescimento problemático
Não faz sentido a empresa que você trabalha crescer 300% ou 400% ao ano se o seu time não tiver saúde mental e tempo para trabalhar da melhor forma num tamanho maior. É bem comum esse cenário em startups que glamourizam horas excessivas trabalhadas por alguma meta irreal. Aquele pico de vendas do produto no meio da noite em que você precisou acordar pra levantar algum serviço da aplicação que caiu pela quantidade de acessos.
Em um mundo realista e respeitável, as máquinas deveriam tomar conta dessas situações ao invés de colocar toda a pressão nas pessoas envolvidas.
Depois de conversar sobre tudo isso. A Torre de Pisa está sustentável.
Na real essa é uma das raras situações onde um bug vira feature haha
E ela não vai cair mais, mesmo que ela continue inclinando. Agora ela está controlada e certeza que isso não é por causa dos turistas que ficam tentando empurrar ela de volta.
A mesma coisa pode acontecer com o programa de Chico. Se nós aplicarmos todas as soluções viáveis, podemos finalmente ter um software sustentável.
Todas as referências que eu usei nessa palestra estão numa Awesome List no Github da Labcodes.