A qualidade do código afeta o estado mental de um programador

A comunicação dentro de sua equipe e os incentivos associados ao seu trabalho. Aprimore seu código e você poderá melhorar sua saúde organizacional e competência como um todo.

O valor de um código de alta qualidade pode ser difícil de comunicar. Alguns gerentes vêem isso como uma bobagem, um hobby caro para programadores excessivamente meticulosos, uma vez que investir na qualidade do código pode retardar o desenvolvimento a curto prazo e não parece alterar a experiência do usuário. Mas nada poderia estar mais longe da verdade. 

 

É verdade que as empresas de tecnologia com um entendimento organizacional pobre da qualidade do código podem ser lançadas rapidamente e ter sucesso no curto prazo. Mas, ao fazer isso, eles incorrem em uma dívida invisível que aumenta toda vez que o código é alterado. Essa dívida não fica intangível por muito tempo. Uma vez que o produto ultrapassa um limite muito baixo de complexidade, o débito vence, consumindo gradativamente a produtividade de sua equipe de desenvolvimento e a usabilidade de seu software . Quando falamos em “ dívida técnica ” , esses são os perigos de que estamos falando.

 

As organizações que produzem software encontram-se na interseção de milhares de variáveis ​​diferentes. Qualquer coisa que afete o estado mental de um programador , a comunicação dentro de sua equipe ou os incentivos associados ao seu trabalho provavelmente se refletirá em seu código. Promover a qualidade do código, então, é parcialmente uma questão de melhorar a saúde organizacional e a competência como um todo. Neste artigo, definirei resumidamente a qualidade do código e explicarei como ela afeta toda a empresa, em seguida, concentre-se em alguns hábitos organizacionais que são eficazes para aumentá-la.

 

O que é qualidade de código?

 

De certa forma, aprender a codificar é aprender a ter empatia com uma máquina: sua atenção intensa aos detalhes, sua necessidade de parênteses correspondentes e capitalização consistente e a impotência de seus estados de erro. Essas necessidades podem ser tão estranhas e opacas que os mais experientes de nós ainda passam horas, até dias, perseguindo bugs que chegam a apenas alguns caracteres do código-fonte. Isso é cansativo. Às vezes, ter empatia com nossas máquinas é o máximo que podemos suportar. Nessas situações, recorremos a uma métrica simples: funciona? Como o propósito principal do código é fazer um trabalho, às vezes não olhamos para além disso.

 

Essa abordagem não é sustentável para qualquer um, mas o menor dos projetos, no entanto. Código não é sudoku, com uma única solução correta para cada problema. Existem infinitas maneiras de escrever qualquer tarefa de computação, e algumas são mais simples e previsíveis do que outras. Pequenas diferenças aqui se somam com o tempo. O código é escrito uma vez e lido mil vezes. Os programadores leem o código quando estão corrigindo bugs ou adicionando funcionalidades. Eles leem o código para lembrar como seus aplicativos funcionam. Eles leem o código para descobrir padrões que podem reutilizar em outro lugar. A única coisa que é feita para o código com mais frequência do que apenas lê-lo é executá-lo. Esta é a razão fundamental pela qual nos preocupamos com a qualidade do código. A utilidade de um trecho de código tem muito a ver com seu impacto nas pessoas que irão lê-lo. Quando escrevemos um bom código, economizamos tempo e esforço. Estamos facilitando o trabalho deles. Estamos fazendo um investimento que renderá dividendos dia após dia, ano após ano, até que o aplicativo chegue ao fim de sua vida.

 

Então, ironicamente, uma vez que treinamos nossas mentes para ter empatia com os computadores para que possamos escrever código funcional, é nossa responsabilidade lembrar como ter empatia com os humanos para que nosso código não os frustre.

 

Como é a qualidade do código em termos mecânicos? Vários livros têm sido escritos sobre o assunto, por isso não vou tentar explicar em profundidade. Mas, para dar uma visão geral, código de alta qualidade é um código que pode ser entendido rapidamente. Se um programador puder escolher um método ou classe de uma base de código aleatoriamente e entendê-lo profundamente em alguns minutos - não apenas sua funcionalidade e lógica de negócios, mas tudo de que depende e de todas as maneiras como pode ser usado - sem consultar muitos outros arquivos , então a base de código provavelmente é de alta qualidade. Uma vez que isso seja alcançado, a questão de saber se o código funciona corretamente é muito menos preocupante; ele pode ser alterado, corrigido ou excluído sem muito risco ou esforço. 

 

Concedido, estou descrevendo um ideal filosófico aqui. Em um aplicativo do mundo real, sempre haverá partes que são inevitavelmente complexas ou confusas. Mas mesmo essas peças podem variar muito em qualidade. Não há situação em que a qualidade do código esteja completamente fora das mãos do programador.

 

Alguns dos fatores mais importantes na qualidade do código são:

 

 

Encapsulamento. O código de alta qualidade é mais frequentemente feito de componentes independentes: não se pode mudar o comportamento de um componente independente modificando algo fora dele, nem o componente modifica coisas que são externas a ele (dentro da razão - ele faz sentido para um componente ler e atualizar um banco de dados se isso for entendido como seu trabalho). Isso economiza tempo de desenvolvimento porque, quando um componente precisa ser consertado, atualizado ou excluído, os programadores gastam menos tempo procurando causas e efeitos externos.

 

Código idiomático. Linguagens de programação modernas têm sintaxe e métodos integrados para as tarefas mais comuns, como converter uma string em um número ou determinar se uma coleção contém um elemento específico. Eles são mais confiáveis, têm desempenho e são amplamente compreendidos do que qualquer coisa que um programador possa escrever do zero e exigem muito menos código do que um método personalizado. O código escrito de forma idiomática - ou seja, usando as convenções e recursos integrados de uma linguagem tanto quanto possível - é mais legível e requer menos manutenção.

 

Nomes significativos. Variáveis ​​e métodos em uma base de código são nomeados pelos programadores que os escrevem. Nomes sem sentido, como `x` ou` fn`, requerem que o programador entenda e lembre-se de camadas extras de contexto enquanto lê o código que as usa. Se houver mais do que alguns deles em um lugar, torna-se impossível manter tudo na memória de trabalho. O código de alta qualidade usa nomes de variáveis ​​específicos e descritivos, como `departmentName` ou` getAnnualExpenses`. Embora seja possível ser muito prolixo aqui, um programador lendo código pela primeira vez é melhor servido por um nome que diz muito do que um que diz muito pouco.

 

Baixa complexidade ciclomática. Sempre que um computador toma uma decisão, como acontece com uma instrução if ou um loop for, outra camada de significado é adicionada ao código a seguir: sob uma condição, o código será executado ou repetido; sob outra condição, ele será ignorado. “Complexidade ciclomática” é uma métrica que se refere ao número de decisões que existem em um processo. Como no ponto anterior, a memória de trabalho de um programador pode se tornar um gargalo à medida que camadas de significado se acumulam. Embora as decisões sejam essenciais para a utilidade de um aplicativo, o código de alta qualidade minimiza os pontos de decisão e o código que eles contêm e evita o aninhamento entre eles, tanto quanto possível.

 

É importante observar que, embora a qualidade do código inclua alguns fatores que podem ser medidos, cada medida concreta da qualidade do código é imperfeita e fácil de jogar. Não há nenhum produto ou ferramenta que possa avaliar de forma automática e definitiva a qualidade de uma base de código. No entanto, existem heurísticas que você pode usar para ter uma ideia da qualidade do código e ver onde podem estar os problemas.

 

Os testes de unidade, por exemplo, são pedaços de código que testam o comportamento do aplicativo. Eles fazem isso de maneira rápida e repetível, garantindo que o aplicativo continue a funcionar corretamente à medida que cresce e muda. Os testes de unidade têm mais probabilidade de acompanhar códigos de alta qualidade do que códigos de baixa qualidade. Eles recompensam e encorajam a qualidade, uma vez que as coisas que fazem um bom código - encapsulamento, acoplamento fraco, concisão, simplicidade e assim por diante - também facilitam o teste. Isso muda o caminho de menor resistência para os programadores: se eles estão escrevendo testes de unidade para código não testado anteriormente, às vezes será mais fácil simplificar e reorganizar esse código do que testá-lo em sua forma atual. E se os programadores sabem que escreverão testes de unidade como uma parte padrão do processo de desenvolvimento, eles são incentivados a escrever um código melhor em primeiro lugar.

 

Os impactos da qualidade do código

 

A natureza dos aplicativos de software é crescer, não apenas em tamanho, mas em complexidade. A complexidade vem em muitas formas. Alguns deles são o resultado de código de baixa qualidade, mas outros são uma parte fundamental da funcionalidade e do valor do aplicativo. A complexidade do software tem valor comercial por alguns motivos:

 

A complexidade de um espaço de problema pode ser absorvida por processos de software. Essa complexidade é transformada, não destruída. O software nunca é menos complexo do que o problema que ele realmente resolve (embora um software bem construído esconda esse fato).

 

Um produto pode se adaptar a uma variedade cada vez maior de casos de uso, adicionando complexidade (geralmente durante a fase de implantação). Isso cria um mercado maior para o produto, ocultando ou personalizando recursos com base em sua relevância para segmentos específicos da indústria, empresas ou usuários.

 

Um bom software é construído de acordo com altos padrões de acessibilidade, capacidade de observação, resiliência e apelo visual. Todas essas coisas exigem código adicional e, portanto, maior complexidade.

 

Complexidade que agrega valor ou aumenta a vantagem competitiva é "boa complexidade". Boa complexidade é a razão pela qual construímos software. A complexidade que torna o código difícil de entender, manter e construir é "complexidade ruim". A complexidade ruim é a principal razão pela qual os produtos de software falham. Boa complexidade faz parte do propósito e do design do software. A complexidade ruim é acidental, aparecendo quando os programadores ou seus gerentes cometem erros durante a implementação (discutirei as causas disso mais tarde).

 

Uma maneira útil de definir a qualidade do código é a relação entre complexidade ruim e complexidade boa. Há grandes vantagens em manter essa proporção baixa - o que venho chamando de "código de alta qualidade".

 

Em primeiro lugar, mantém os custos de desenvolvimento e manutenção baixos a longo prazo. Considere o seguinte gráfico:

 

 

Para qualquer projeto que dure mais do que algumas semanas, a velocidade de desenvolvimento depende parcialmente da qualidade do código. Esse é um fator significativo no custo total de propriedade - em outras palavras, o resultado financeiro da empresa está diretamente em risco. Um estudo descobriu que a complexidade é responsável por 25% do custo de manutenção do software e mais de 17% dos custos totais do ciclo de vida do software. E uma pesquisa de 2018 feita por Stripe descobriu que o custo mundial de lidar com “códigos ruins” chega a US $ 85 bilhões por ano. Esses números tratam apenas dos custos em termos de tempo de desenvolvimento e folha de pagamento; também vale a pena considerar os custos de envio de software defeituoso ou de chegar ao mercado por um concorrente. Uma vez que os efeitos do código incorreto persistem até que seja removido, a única abordagem sensata é lidar com ele o quanto antes e com frequência.

 

Em segundo lugar, a qualidade do código é um fator de satisfação no trabalho entre os programadores. As empresas que desejam atrair talentos de classe mundial, aumentar o engajamento dos funcionários e limitar a rotatividade não podem ignorar esse relacionamento. A rotatividade, em particular, é um fator estudado no sucesso ou no fracasso de projetos de software. Provavelmente, os programadores cometem mais erros em projetos com os quais estão menos familiarizados.

 

Terceiro, a qualidade do código impulsiona a qualidade do produto. O código de alta qualidade tem menos probabilidade de ter bugs , que são os principais impulsionadores das reclamações dos usuários. A qualidade do código também foi correlacionada ao sucesso comercial e à redução das vulnerabilidades de segurança . A qualidade do código certamente não é o único fator no desempenho de um produto no mercado, e provavelmente também não é o fator mais importante. Mas mesmo as organizações mais competentes terão dificuldade em comercializar um produto infestado de insetos ou vulnerável a hacks.

 

Como as organizações podem aumentar a qualidade do código

 

A qualidade do código requer investimento. Não pode ser aumentado sem o comprometimento de recursos - dinheiro, tempo de desenvolvimento e negociação de prazos sendo os mais importantes. Também não pode ser aumentado pelo uso de ameaças, punições ou horas extras; o código não pode ser melhorado nas condições que levam a um código incorreto em primeiro lugar! A boa notícia é que a refatoração - a prática de aumentar ativamente a qualidade de uma base de código - não exige que todas as outras atividades de desenvolvimento sejam interrompidas. Pode se tornar uma parte regular e com o mínimo de interrupções do processo de desenvolvimento, algo que a equipe cuida enquanto continua a construir e melhorar os recursos.

 

A seguir estão alguns hábitos e competências organizacionais que promovem códigos de alta qualidade.

 

Ritmo sustentável

A programação é difícil nas melhores circunstâncias. Conforme mencionado anteriormente, a capacidade de um programador de codificar depende profundamente de seu estado mental. Felicidade, descanso suficiente e baixos níveis de estresse são ingredientes importantes. 

 

A primeira maneira de garantir que os programadores tenham recursos mentais suficientes para fazer seu melhor trabalho é evitar horas extras . A qualidade do código de um programador cai ao final de um dia de trabalho padrão de oito horas, muito menos nas horas seguintes. Muitos programadores tiveram a experiência de programar quando estavam excessivamente cansados, estressados ​​ou doentes, descobrindo no dia seguinte que todo o seu trabalho precisava ser desfeito ou reescrito. Este é um “trabalho negativo líquido”, um código de qualidade tão baixa que realmente aumenta a quantidade de trabalho restante no projeto. Nada pode compensar a falta de descanso a longo prazo - nem cafeína, nem micro-cochilos, nem mesas de pingue-pongue, nem cerveja grátis podem replicar os benefícios de uma noite tranquila e uma boa noite de sono.

 

As empresas que promovem o esgotamento insistindo em horas extras constantes não são apenas abusivas, mas também autodestrutivas. Quaisquer ganhos iniciais de produtividade serão rapidamente abafados pela má qualidade. Por outro lado, as empresas que acompanham suas equipes de desenvolvimento em uma jornada de trabalho curta, sustentável e flexível, permitindo bastante tempo livre e licença médica, podem esperar resultados consistentes e de alta qualidade em longo prazo.

 

Uma causa comum de horas extras em organizações competentes é a pressão de prazos. Os prazos costumam ser baseados em motivações financeiras ou preocupações com a programação, e não nas realidades do desenvolvimento de software. Os programadores não podem acelerar um projeto pensando mais ou digitando mais rápido. Quando o prazo se aproxima, eles geralmente pegam o único atalho de que dispõem, que é a redução da qualidade. Isso pode ser evitado com um planejamento cuidadoso e estratégias em torno dos prazos.

 

A primeira parte disso é a estimativa. A estimativa de software é uma habilidade complexa que requer treinamento específico . A maioria dos programadores e gerentes não teve esse treinamento. Na ausência de habilidades de estimativa, as equipes correm o risco de cair em fórmulas supersimplificadas, como "adivinhe quanto tempo vai demorar, depois dobre essa estimativa e, em seguida, dobre novamente". O melhor cenário aqui é que o projeto seja concluído cedo e os gerentes de projeto sejam deixados improvisando maneiras de preencher o tempo de desenvolvimento restante. Mas o pior cenário é que o projeto seja entregue com atraso ou mal funcione. Portanto, se uma organização não tiver tempo ou vontade para desenvolver habilidades de estimativa de software, é muito melhor negociar prazos extremamente generosos do que acabar decepcionando os clientes.

 

A segunda parte do gerenciamento de prazos é a priorização. A priorização não é apenas sobre quais coisas são construídas primeiro; é sobre como as coisas são construídas. Todo roteiro de desenvolvimento pode incluir recursos supervalorizados (difíceis de construir e não especialmente valiosos para os usuários) ou subestimados (fáceis de construir e muito valiosos para os usuários). Um gerente eficaz concentrará os esforços de sua equipe na última extremidade do espectro, especialmente à medida que os prazos se aproximam.

 

Se os prazos forem bem gerenciados, eles podem ser um motivador eficaz para as metas de entrega de software da equipe, ao mesmo tempo que deixam tempo suficiente para que as coisas sejam construídas da maneira certa. A qualidade do software, tanto quanto qualquer outra coisa, requer tempo dedicado.

 

Refatoração como parte do ciclo de desenvolvimento

 

A dívida técnica, como uma erva daninha, surge independentemente do que possamos fazer para evitá-la. Embora algumas práticas de desenvolvimento possam reduzi-lo substancialmente, não há como eliminá-lo sem o benefício de uma retrospectiva. Mantê-lo no mínimo significa reservar um tempo regularmente para encontrar, discutir e consertar.

 

Muitas organizações usam a “regra dos 20%” como guia: 80% do tempo de desenvolvimento é gasto no desenvolvimento de recursos ou correções de bugs e 20% é gasto na refatoração. Esse princípio funciona melhor quando aplicado livremente, uma vez que as equipes não podem prever exatamente quanto tempo uma determinada tarefa levará. E pode haver ciclos ocasionais em que o débito técnico se tornou um obstáculo a ponto de exigir total atenção da equipe, ou ciclos quando há lançamentos urgentes de recursos para atender e o débito técnico fica em segundo plano. A organização deve tomar cuidado para não cair na armadilha de fazer qualquer uma dessas coisas por mais tempo do que o necessário.

 

Para obter os melhores resultados, as tarefas técnicas da dívida devem ser cidadãos de primeira classe do processo de planejamento. Ou seja, eles devem coexistir com recursos, bugs e tarefas de teste no software de planejamento da equipe (ou em seu quadro branco, conforme o caso). A regra dos 20% pode ser adotada simplesmente como "uma em cada cinco tarefas é reservada para refatoração". Isso não exige necessariamente que as tarefas de dívida técnica sejam planejadas e definidas com o mesmo nível de detalhe das tarefas de recursos. Em vez disso, o objetivo é garantir que o trabalho de refatoração da equipe seja visível e o tempo gasto nele seja protegido.

 

Liderança técnica e revisão

 

A qualidade do código é uma segunda natureza para muitos programadores. Eles reconhecem código de baixa qualidade, entendem seus efeitos e sabem como corrigi-lo. Para outros programadores, o conceito é totalmente estranho. Se um projeto for inteiramente realizado por este último, não demorará muito para que ele termine atolado em um desenvolvimento lento e em problemas técnicos.

 

Qual é a diferença entre esses dois grupos de programadores? A resposta é simples: estudo e prática intencional. Infelizmente, nem as faculdades, nem os bootcamps, nem os anos de experiência no setor podem ser considerados para incutir as habilidades relevantes - nada no currículo de um programador irá necessariamente separá-los. Mas isso não deve manter a contratação de gerentes à noite. A qualidade do código e as habilidades de refatoração podem ser aprendidas em qualquer estágio da carreira de um programador e são muito menos complexas do que muitos dos outros conceitos com os quais lidam. A qualidade do trabalho de um programador pode aumentar dramaticamente ao longo de alguns meses se ele tiver acesso aos recursos certos e estiver disposto a melhorar.

 

Além do mais, uma organização de software pode prosperar mesmo quando seus programadores são desigualmente qualificados. Se programadores experientes forem escolhidos para liderar a arquitetura, design e planejamento de projetos de software, sua compreensão da qualidade do código fará parte do DNA do ciclo de desenvolvimento. Esse tipo de liderança técnica é essencial para software de alta qualidade.

 

As lacunas de habilidades também podem ser colmatadas com várias formas de revisão:

 

As revisões de design acontecem depois que uma tarefa é especificada, mas antes que qualquer código seja escrito. O programador designado para a tarefa escreve um documento descrevendo sua abordagem: os arquivos, classes e métodos que eles planejam atualizar; os padrões e técnicas que usarão; e quaisquer incertezas que possam ter sobre o design ou a lógica de negócios. Em seguida, outro programador dá feedback sobre esse documento, o que pode incluir a correção de equívocos e a sugestão de padrões ou métodos úteis que já existem na base de código. O tempo gasto por esse processo às vezes é substancial, mas é um investimento que vale a pena. Detectar um defeito tão cedo no processo de desenvolvimento é extremamente barato em relação ao custo de descobri-lo e consertá-lo posteriormente.

 

A programação em pares é a prática de designar dois programadores para concluir uma tarefa juntos em tempo real. Um programador controla o teclado e o mouse enquanto o outro programador dá instruções. Isso permite revisão instantânea, feedback e transferência de conhecimento durante o desenvolvimento. Estudos encontraram resultados mistos quanto à produtividade bruta de dois programadores trabalhando juntos versus solo (embora pareça oferecer um aumento de produtividade mais consistente para programadores inexperientes). No entanto, quando a qualidade do código é levada em consideração, a programação em pares é quase universalmente reconhecida como vantajosa.

 

As revisões de código acontecem depois que o código é escrito, mas antes de ser enviado como parte do produto. Um programador disponibiliza suas alterações de código para o resto da equipe. Em seguida, outro programador os lê e dá feedback, geralmente sugerindo mudanças que devem ser feitas antes de o código ser enviado. Muitos problemas de qualidade de código só podem ser reconhecidos por um ser humano. Esta é a última oportunidade de pegá-los antes que se tornem parte do produto.

 

Se os membros da equipe são freqüentemente solicitados a verificar o trabalho uns dos outros e não há grandes hostilidades ou falhas de comunicação entre eles, a qualidade de seu trabalho coletivo aumentará para o nível do programador mais experiente.

 

A qualidade do código é uma vantagem competitiva

 

A pesquisa sobre a qualidade do código não é escassa (se os mais de 25 estudos vinculados acima não forem suficientes, há muitos mais ). Repetidamente, ele demonstrou ser um fator de sucesso ou fracasso do projeto, tempo de colocação no mercado e longevidade do produto. As organizações que priorizam bases de código saudáveis ​​estão priorizando seus clientes, seus programadores e sua própria viabilidade financeira.

 

A qualidade do código também é um dos grandes presentes que nós, programadores, podemos dar a nós mesmos e aos nossos colegas. Se gastarmos alguns momentos extras nomeando uma variável, reescrevendo uma lógica profundamente aninhada ou tornando uma função mais previsível, esses momentos serão reembolsados ​​na íntegra muitas vezes conforme interagimos com aquele código ao longo da vida do projeto. Pensar sobre como nosso código afeta os computadores é o mínimo; pensar sobre como nosso código afeta os humanos é uma forma poderosa de empatia na prática, que nenhuma organização pode se dar ao luxo de ignorar.


Strong

5178 ブログ 投稿

コメント