
Para muitas equipes, refatorar é uma dor. Porque se você refatorar, não desenvolverá o produto principal e, se não o fizer, a dívida técnica do projeto aumentará. Em algum momento, as equipes pensam: "Vamos distinguir entre refatoração e desenvolvimento e alocar, por exemplo, 20% de nossas horas trabalhadas, e pelo resto do tempo continuaremos engajados no desenvolvimento!" Essa idéia não é ruim, a única coisa é que a cada 100 horas de desenvolvimento você nunca terá 20 horas puras de refatoração. Porque "desenvolvimento" não é apenas trabalhar com código.
Se estamos falando de equipes maduras, em vez de mini-equipes compactadas em um ponto material para 3 a 5 pessoas, o "desenvolvimento" inclui uma série de atividades diferentes da equipe, além de escrever código. No "desenvolvimento", você pode anotar reuniões tão mal amadas por muitos, trabalhando com a documentação, mantendo relatórios nos gerenciadores de tarefas e assim por diante. Tudo isso consome cerca de 30% de nossos relógios alocados para desenvolvimento. E de alguma forma, despercebido, acontece que, em vez da figura “80 horas de código, 20 horas de refatoração”, obtemos uma figura feia de ~ 13 horas para, diretamente, a própria refatoração, porque todo o resto foi absorvido por outras atividades.
Abaixo, mostraremos como combinar desenvolvimento e refatoração para que a dívida técnica do projeto não cresça como uma bola de neve, mas também fale sobre a distribuição correta de tempo e priorização.
Por que a refatoração causa tantos problemas? Primeiro, devido ao fato de as equipes não poderem avaliar adequadamente seus próprios recursos e combinar esse processo com o desenvolvimento. Parece às pessoas que, se o dia de trabalho é de 8 horas por dia (40 por semana), então todas as 40 horas estão supostamente envolvidas no desenvolvimento. Isto não é verdade.
Todo o processo de desenvolvimento pode ser dividido em duas partes: são atividades paralelas e tudo que está diretamente relacionado ao código.
Veja como é a distribuição de tempo de uma de nossas equipes de desenvolvimento.O leitor pode ter uma pergunta razoável: "como você construiu este diagrama?" e agora vamos tentar dar uma resposta. Os dados não foram retirados do teto, mas com base em nossas estatísticas internas. Nossos desenvolvedores acompanham suas atividades em Jira. Cada registro de trabalho pessoal consiste em quatro seções: revisão de código, discussões técnicas, tickets específicos e "tudo o resto". Graças a essa classificação bastante simples e transparente, construímos uma análise de quanto tempo gastamos em equipes em cada aspecto do desenvolvimento. Se um terço de todo o tempo de trabalho cai em reuniões, stand-ups e revisões - tudo está dentro da faixa normal. Se mais de 33% são gastos nessas atividades, a equipe tem problemas e precisa ser tratada.
Parece que não há problema e tudo é lógico, mas como encaixar a refatoração nessa história? Declarar um "mês de refatoração" e pontuar no desenvolvimento? No entanto, qualquer produto comercial tem seu próprio cronograma, o que é extremamente indesejável. Ainda assim, a refatoração é como um atoleiro: se você começou a lidar com isso, é difícil parar, é atraído para esse ponto. A refatoração muda o foco da atenção da equipe para si mesma, e temos um viés monstruoso em direção à "ordem de restauração" no código já escrito, em vez de mudar o projeto para um futuro melhor. Então, como distribuir o tempo?
O slide a seguir fornece algumas respostas:
Mantenha registros de tempo, é extremamente útilReuniões e revisões permanecem intocadas, porque acreditamos que essas atividades são otimizadas o máximo possível e mantidas em um nível mínimo adequado (aqueles que trabalharam em equipes nas quais reuniões e revisões de código levaram 70% do tempo confirmarão nossas palavras). Portanto, reservamos um tempo para refatorar o código e as correções de erros do desenvolvimento. E aqui novamente aplicamos a abordagem "um e dois terços" e dividimos as horas de trabalho recebidas por nós em "refatoração" e "erros", separando claramente esses conceitos. Esse modelo é viável e permite que você encontre tempo para restaurar a ordem no projeto, pelo menos sem aumentar a dívida técnica. Se gastarmos muitas horas de "desenvolvimento", o projeto será interrompido.
Abordamos o processo de refatoração corretamente
Suponha que você decida refatorar em vez de reescrever um projeto do zero. Mas aqui você não pode pegar o primeiro e refatorar como no exército ", daqui para almoçar". Como nossos recursos são limitados e nosso objetivo é interromper o crescimento da dívida técnica (e, idealmente, obter uma redução em seu tamanho), devemos abordar essa tarefa com sensibilidade.
A melhor solução parece permitir que o líder da equipe ou outro gerente de desenvolvimento determine o escopo do trabalho, atribua tarefas e prossiga com a refatoração. Mas esta opção tem uma falha séria. Timlid é o condutor da nossa equipe, mas os problemas dos músicos locais nem sempre são óbvios para o condutor. Se você é um defensor de uma vertical rígida e de um modelo no qual uma pessoa decide como a refatoração ocorrerá, sente-se voluntariamente no KAMAZ em chamas, que com freios quebrados corre da montanha para o abismo.
Nossa experiência mostra que uma versão robusta do desenvolvimento de eventos é uma definição coletiva de várias direções de refatoração, ou seja, os desenvolvedores devem participar da compilação de uma lista de trabalhos futuros. Somente o autor imediato do código pode admitir honestamente se esta seção foi adequadamente fechada ou, devido à falta de tempo, várias muletas foram empilhadas lá em cima. Além disso, são os desenvolvedores que estão na vanguarda da tecnologia e são capazes de avaliar com sensibilidade quais elementos de um projeto precisam ser refatorados e quais não devem ser tocados.
Para nós mesmos, criamos essa abordagem: cada um dos desenvolvedores se lembra dos pontos fracos do projeto e escreve um cartão sobre o que precisa ser feito para torná-lo melhor. Nesses cartões, as tarefas serão determinadas. É verdade que há uma nuance: após o primeiro cartão recebido no estilo "fazer bem" sem nenhum contexto, começamos a exigir esse contexto de forma compactada.
Os mesmos cartõesMas definir uma tarefa não é suficiente para iniciar sua implementação. Portanto, uma lista de verificação deve ser compilada para cada um desses cartões, o que responde a uma série de perguntas simples como "Precisamos fazer algo em paralelo?" ou "Existem fatores que nos impedem de concluir esta tarefa?" Após preencher essa lista de verificação, o desenvolvedor recebe uma lista específica de todos os possíveis problemas e bloqueadores que precisam ser resolvidos na fase dos trabalhos preparatórios.
Outra etapa obrigatória é determinar quem está em quais áreas do projeto quem sabe melhor. Isso otimizará o processo de refatoração e fornecerá aos membros da equipe tarefas nas áreas em que eles podem se provar melhor. É verdade que um dia nos deparamos com uma situação em que uma pessoa e meia normalmente entendia um aspecto do projeto, mas mesmo esse problema pode ser resolvido. Para eliminar o vácuo de informações, os desenvolvedores que ainda “vasculham” a área onde o restante da equipe passa, devem compartilhar seus conhecimentos. Pode ser documentação, algum tipo de mini-apresentação, até um vídeo com explicações do código. É importante transmitir informações aos colegas e garantir que haja o menor número possível de pontos escuros.
E, finalmente, a equipe deve responder claramente à pergunta "qual é o tamanho da nossa dívida técnica?" Classes como "grau C", "aceitável", "cinco em cada dez", "você pode viver" não funcionam mais. Anteriormente, respondíamos “um em cada dez” em uma pergunta semelhante da estação de serviço para um dos projetos e, quando convertemos o valor da dívida técnica em números, obtivemos 650 horas. Foi estranho. Somente uma resposta clara a essa pergunta ajudará a avaliar com sensatez o escopo dos próximos trabalhos. Isso também é importante porque as tarefas “intermináveis” matam a motivação dos membros da equipe e enfurecem os negócios: tanto os desenvolvedores quanto a gerência devem ver algum ponto final tangível pelo qual a equipe se empenhará.
Priorização
Depois de definir a frente do trabalho, precisamos combinar a refatoração com o desenvolvimento. Obviamente, não podemos parar de serrar recursos em diferentes partes do projeto ou alocar um tempo especial para este evento.
É aqui que começa a parte mais difícil. A equipe de desenvolvimento deve determinar sensatamente em quais momentos o desenvolvimento é mais importante e em que refatoração é importante, especialmente quando algum recurso está sendo visto neste momento no código. Talvez, após a refatoração, o desenvolvimento posterior seja mais fácil e, em alguns casos, possamos concluir nosso recurso e só então refatorar. Nós nos comunicamos com o produto, discutimos a decisão e concordamos com qual será o pedido. Por exemplo: "Vamos refatorar primeiro - não apenas porque queremos, mas porque o prazo total será menor no final".
O mais importante é não esquecer que nosso objetivo é desenvolver um produto e não escrever o código perfeito em prol do código perfeito ou da completa eliminação da dívida técnica. O desenvolvimento deve ser totalmente adequado a esse respeito: se a refatoração no momento prejudicar nossa tarefa de desenvolvimento de negócios, terminaremos de escrever um novo código e somente então corrigiremos o antigo. Se as circunstâncias disserem que será mais lucrativo para o projeto refatorar esta seção (não importa o quão monstruosa seja a frente do trabalho), uma vez que trabalhos futuros serão mais simples e divertidos, precisamos refatorar.
Essa abordagem se encaixa extremamente mal no modelo de gerenciamento vertical e, às vezes, você encontra situações em que precisa defender suas decisões na frente do cliente. Mas por outro lado nada.
O que obtemos como resultado
Com a abordagem descrita, integramos organicamente os processos de refatoração no desenvolvimento atual, reduzimos o tamanho (ou interrompemos o crescimento) da dívida técnica e tudo isso sem grandes perdas.
Sim, para fins de refatoração, você terá que reduzir o tempo para desenvolver novos recursos, o que aumentará o tempo, mas a escolha é pequena: você refatora em paralelo com o desenvolvimento ou, mais cedo ou mais tarde, chega a uma quantidade tão grande de muletas, problemas e bugs que será mais fácil reescrever o projeto do zero. Portanto, se você valoriza o trabalho de sua equipe, ainda deve pensar em refatorar em vez de reescrever no futuro.
Materiais úteis:1. Relatório de Alexey Kataev sobre refatoração: exemplos mais práticos, bem como uma história incrível do gerente Gleb, que ainda não queria refatorar ...
2.
Nossos regulamentos para discussão de tarefas3.
Nossa revisão do código da lista de verificação