Clean Code: reduzindo custos com desenvolvimento e manutenção
Por Kaique Prazeres
Desenvolver sistemas com grande longevidade e fácil manutenção é um desafio comum enfrentado pela maioria dos times de engenharia de software. Isso requer mais que conhecimento técnico em padrões ou tecnologias do momento, pois envolve a capacidade de tomar decisões durante o processo que impactarão na experiência do próprio desenvolvedor que irá dar a manutenção no sistema.
Enquanto direcionamos a maior parte dos esforços para a parte inicial do desenvolvimento de um novo sistema, a atenção com aspectos que facilitarão a manutenção no futuro continuará sendo negligenciada.
Passamos a maior parte do tempo estudando e lendo código escrito por outros desenvolvedores e muitas vezes, nos deparamos com trechos difíceis de entender, fazendo com que a maior parte do tempo investido seja apenas para a compreensão do que com a evolução de implementações.
Neste artigo, você conhecerá algumas técnicas de Clean Code que ajudam a reduzir os custos de desenvolvimento e manutenção e que também equilibram o tempo de compreensão com o tempo de evolução de novas implementações no código.
O que é Clean Code e por que aplicar suas técnicas?
O próprio nome já diz, mas de acordo com o livro, Clean Code, escrito por Robert C. Martin, “é um conjunto de atributos de qualidade aliado a boas práticas que garantem que um código possibilite fácil manutenção em todos os aspectos” . Em resumo, é um código simples, eficiente, testável, fácil de entender, de se manter, evoluir e reaproveitar independente de quem escreveu – seja júnior, pleno, sênior, desenvolvedor, analista, engenheiro ou arquiteto.
Mas por que aplicar as técnicas de Clean Code durante o desenvolvimento e manutenção?
- Manter um código limpo;
- Reduzir a dívida técnica;
- Aumentar a produtividade do time, inclusive com novos membros;
- Alcançar uma vantagem competitiva na velocidade de desenvolvimento em comparação com o concorrente;
- Maximizar o valor futuro;
- Evitar que o software se torne legado devido à complexidade na manutenção
Os motivos listados acima poupam incontáveis horas gastas com recursos que poderiam estar focados em construir uma nova solução, implementando melhorias que gerem valor para o negócio e para o próprio time de desenvolvimento, de forma rápida ou pensando nas próximas funcionalidades.
Também evitará que o produto acumule dívidas técnicas impagáveis, ou seja, impedirá que, no futuro, gastemos mais horas de trabalho em itens técnicos que já deveriam ter o mínimo de qualidade garantida. Em outras palavras, retrabalho.
Além disso, à medida que essa confusão aumenta, a produtividade diminui a quase zero. E é isso que as técnicas do Clean Code nos ajudam a evitar. Nos fazendo refletir sobre o impacto financeiro gerado e sobre a relação entre produtividade, qualidade e manutenção.
6 Técnicas de Clean Code
1 – Regra do escoteiro
Não basta escrever um código bom, é preciso melhorá-lo cada vez que o revisitarmos, pois qualquer código limpo pode ficar sujo com o tempo, por isso é importante ter a constante prática de melhoria contínua.
Mas isso não se limita ao mesmo trecho do código que foi desenvolvido ou alterado, e sim a qualquer parte dele. Não precisa ser algo grande, pode ser a troca do nome de uma variável, constante, método, função, classe ou eliminar uma pequena duplicidade de código.
Por que utilizar? Pois quando isso se torna um hábito, não há espaço para bagunça, para fazer as coisas de qualquer jeito independente do prazo ou pressão que ocorra. É uma questão de mentalidade e cuidado com a qualidade do trabalho realizado.
Em resumo, essa prática evita que horas extras sejam dedicadas no futuro só para entender o que é e como foi feito.
2 – Use nomes a partir do domínio da solução
Todas as instruções contidas no código devem ser compreensíveis por outros desenvolvedores e por todos os envolvidos no projeto.
Então, na prática, se algum analista de negócio ou responsável por um departamento da empresa fala um termo específico em suas orientações de como quer que o sistema funcione, o termo deve ser utilizado quando o código for escrito e isso deve ser feito sem adaptações.
Por que utilizar? Isso facilitará para outros desenvolvedores o que significa aquele termo. Por exemplo, pense em um sistema que está sendo desenvolvido para um banco, e o termo “francesinha” é mencionado pelas pessoas envolvidas no projeto, sendo que o termo represente o extrato de movimentação de títulos mantidos na carteira de cobrança bancária. A maioria das pessoas envolvidas com o contexto bancário está habituada com este termo.
Agora imagine o cenário em que o desenvolvedor acha o termo cômico ou não gosta dele e resolve escrever outro termo para substituir, como “XPTO” e implementa isso nas telas do sistema e no código.
Provavelmente os usuários que utilizam o app e estão acostumados com o termo ficarão sem entender o que significa “XPTO”, pois terão a sensação de que a funcionalidade “francesinha” deixou de existir. E não só os usuários, mas também nas reuniões que envolvem entendimento das regras de negócio que utilizam o termo para desenvolvimento de outras funcionalidades. E novos desenvolvedores que atuarem no projeto, pois serão aculturados com o termo errado que não é conhecido pelos envolvidos.
Usar nomes a partir do domínio da solução, ajuda o time a não perder tempo inventando termos não utilizados pela área de negócio e evita que desenvolvedores percam tempo tentando tirar dúvidas sobre o que significa enquanto poderiam estar focados em evoluir o que já existe com base no entendimento comum sobre os termos específicos da área de negócio.
3 – Use nomes passíveis de busca
“Usar nomes passíveis de busca” é uma técnica que está diretamente conectada a técnica de “Usar nomes a partir do domínio da solução”.
Durante o desenvolvimento do código-fonte é comum desenvolvedores buscarem atalhos para driblar a necessidade de pensar e dar nomes. Aliás, boa parte do desenvolvimento de sistemas consiste em “dar nome aos bois códigos”.
Utilizar nomes de fácil busca é uma técnica que guia a escolha dos termos empregados no código de um software, incluindo variáveis, funções, classes e métodos, bem como nos arquivos frequentemente modificados. Essa prática visa facilitar a pesquisa e compreensão do código. De forma que tenham uma identificação própria ou represente alguma informação de forma lógica. Diferente de usar apenas letras, códigos ou abreviações que só quem desenvolveu determinado trecho de código consegue entender.
Por que utilizar? Essa técnica facilita a busca durante a manutenção. Os desenvolvedores podem facilmente identificar a função de determinados trechos de código pelo nome atribuído e pelo seu contexto. Reduzindo a quantidade de tempo necessária para entender o que cada trecho faz ou o que significa.
Um exemplo comum, que pode representar de forma prática quanto tempo se perde não usando nomes passíveis de busca, é o código que tem uma série de variáveis, funções, classes, métodos e arquivos com abreviações de termos verbosos (grandes) e letras como “i”, “a”, “j” que são utilizadas.
Agora, imagine quanto tempo o desenvolvedor que dará manutenção em um código cheio de letras e siglas que não representam nenhum conceito de negócio levará para realizar a entrega esperada pela área de negócio simplesmente porque “não deu nome aos bois códigos”? Podemos poupar gastos com horas e horas através dessa técnica.
4 – Evite o mapeamento mental
Outra técnica que orienta o cuidado com os nomes dados nos códigos. Todo nome deve ser significativo e claro, seja de variável, funções, classes, arquivos, ou etc. Em resumo, isso significa que devem ser óbvios.
O mapeamento mental faz com que desenvolvedores que tem contato com o código tentem adivinhar o que significa cada trecho. Inclusive o significado de siglas, letras, números perdidos e nomes que só fazem sentido na cabeça de quem escreveu o código.
Por que utilizar? Pelo mesmo motivo que usar nomes a partir do domínio da solução e usar nomes passíveis de busca facilitam a procura e a compreensão por parte de quem está dando manutenção.
Isso reduz a quantidade de horas gastas com tentativas de entendimento do código que sofrerá alterações a curto, médio e longo prazo. Essa quantidade de horas não gasta, é uma grande economia, podendo em alguns casos economizar uma ou mais sprints.
5 – Evite repetição
Essa técnica está diretamente ligada a um princípio da própria programação, o DRY (Don’t Repeat Yourself). Como o próprio nome da técnica e o princípio afirmam: Evite repetição.
Ou seja, evite repetir trechos de código e permita a reutilização por meio de estruturas que demandam com pouco esforço, seja por meio de uma função, método, classe, arquivo etc.
Por que utilizar? A repetição de código gera um efeito colateral que aumenta exponencialmente o consumo de horas em uma manutenção.
Como? Quando você altera uma funcionalidade ou módulo com vários trechos de código repetidos e dispersos que executam a mesma função, qualquer modificação em uma regra ou trecho exigirá mudanças em várias outras partes. Em sistemas de médio e grande porte isso é um verdadeiro caos, pois quanto mais pontos duplicados houver, mais consumo de hora será necessário para alterá-los.
Haverá perda de horas com:
- Identificação de trechos duplicados;
- Alteração da mesma regra em vários pontos do sistema;
- Verificação de trechos não atualizados por esquecimento;
- Investigação da causa de um problema decorrente da cópia e duplicação de código sem avaliação detalhada
Evitar repetição de código ajuda a reduzir o tempo de desenvolvimento e manutenção através do reaproveitamento, que é garantido conforme o código é modularizado. Isso reduz o tempo de horas gastas com pesquisas das duplicações, acabando com o risco de gerar bugs a partir da prática de copiar e colar sem especializar o trecho. Além disso, previne bugs causados por esquecimento de uma atualização do trecho repetido em cada parte do sistema.
6 – Use constantes ao invés de números mágicos
É comum encontrar em métodos e outros trechos de código números fixos, sendo usados muitas vezes para comparação, cálculo, ou como limite numérico. Porém um número sozinho pode não expressar por si só o que representa no código. Isto é o que chamamos de número mágico.
Mas os números mágicos podem atrapalhar o entendimento geral de um trecho de código por não explicitar uma lógica de negócio ou o que ele representa. Imagine encontrar no código um número 1, 3 ou 7 perdidos e não saber o que eles significam? Agora imagina o tempo gasto para entender isso, ou o tempo buscando disponibilidade de alguém da área de negócio para talvez ajudar a entender algo a respeito? Poderíamos otimizar esse tempo com o uso de constantes, destinando o esforço inteiramente à evolução da funcionalidade associada a este código.
Por que utilizar? Substituir números mágicos por constantes ajuda a reduzir custos com manutenção de 3 maneiras:
- O significado do número é claro no código, basta verificar o nome da constante;
- Utilizar uma constante indica que o valor permanecerá constante durante a execução, sendo fixo e alterado apenas se necessário para o negócio;
- Quando o número é usado repetidamente no código ou em outros arquivos, é possível reutilizar a mesma constante.
Utilizar constantes ajuda não somente por exprimir melhor a utilidade de tal número, também a detectar facilmente onde o número é utilizado. Também verificando se há outros números associados e entendendo o que representam em cada contexto, além de permitir o reaproveitamento.
Como essas técnicas de Clean Code ajudam a reduzir os custos na prática?
Aumentando a eficiência na manutenção ou evolução de funcionalidades através de práticas que reduzem o tempo e esforço necessário de entendimento e implementação do “que” e do “como” será feito no código.
Portanto, a produtividade dos times de engenharia de software também está associada à qualidade técnica dos projetos. E quanto menor a qualidade técnica, maior é o custo de manutenção.
De acordo com o artigo gerado a partir do estudo Clean Code: On the Use of Practices and Tools to Produce Maintainable Code for Long-Living Software, a escolha de procedimentos e práticas é mais cultural do que problema técnico.
Tendo isso em mente, o time que prioriza a adoção de práticas que aumentam a eficiência da manutenção e pensam no longo prazo, tendem a poupar futuras modernizações e dificuldades de evolução em funcionalidades existentes.
A aplicação do Clean Code incentiva uma atuação proativa focada em longo prazo. E a comprovação dos resultados é possível através de uma comparação com cenários que envolvem sistemas que não aplicaram essas técnicas.
Clean Code investimento evolutivo
Medimos sistemas de sucesso pela capacidade de adaptação e extensibilidade para permitir uma rápida evolução frente as necessidades de negócio e de mercado. Contudo, infelizmente, a maioria dos sistemas são construídos sem que boas práticas e técnicas que facilitam a manutenção sejam consideradas.
Então, quanto mais bem-sucedido o sistema, maior será sua longevidade e menor será a incidência de problemas. Para evitar que a manutenção dos sistemas se torne um desafio oneroso para as empresas, consumindo horas que poderiam ser direcionadas para o desenvolvimento focado no negócio, é fundamental aplicar técnicas de Clean Code por meio de um processo contínuo e incremental.
Ademais, podemos comprovar e medir empiricamente os ganhos da aplicação dessas técnicas no dia a dia, à medida que os sistemas que estamos desenvolvendo evoluem. E, em conclusão, investiremos financeiramente na evolução, em vez de gastar com manutenção.
Referências
Martin, Cecil Robert. Clean Code. 2008.
Clean Code: On the Use of Practices and Tools to Produce Maintainable Code for Long-Living Software
Kaique Prazeres é Arquiteto de Soluções na Operação Nacional da Programmers e é um ferrenho defensor de boas práticas e qualidade de software com foco em redução de custos e aumento de longevidade de sistemas.