CLEAN CODE – O que é, e como aplica-lo de maneira correta
Um problema constante na vida de desenvolvedores e programadores é a manutenção de código desenvolvido por outro profissional, e a qualidade desse é o termômetro da qualidade profissional da empresa e do desenvolvedor. Não é incomum se deparar com um código ruim, mal escrito, mal documentado, sem um padrão, isso gera prejuízos altíssimos como atrasos na entrega, custos muito altos de manutenção, além de prejuízos financeiros com falhas e brechas de segurança que comprometem não só as empresas de software como também os usuários. Visando resolver ou pelo menos mitigar esses problemas muitas metodologias foram desenvolvidas, vamos falar um pouco sobre elas?
Clean Code
CLEAN CODE ou código limpo se traduzido ao pé da letra, foi um termo cunhado pelo autor e programador Robert Cecil Martin (Uncle Bob, como é conhecido) que é também um dos profissionais que contribuiram com o Manifesto Ágil, outra metodologia de desenvolvimento de software.
Consiste na aplicação de regras simples, que facilitam a escrita, leitura, entendimento e interpretação de um código por nós humanos de maneira simplificada. Isso gera uma maior agilidade na correção de falhas e implementação de novas funcionalidades, menor tempo de desenvolvimento, menores custos para a manutenção e a facilidade em recolocar ou re arranjar equipes trazendo melhor integrabilidade entre as pessoas.
Durante sua carreira como desenvolvedor, Uncle Bob descobriu que o maior problema no ciclo de vida de um software era a manutenção em média um programador gasta 10 (dez) vezes mais tempo lendo código do que propriamente escrevendo, e um código limpo e bem feito reduz esse tempo de maneira assustadora, gerando um melhor rendimento.
É comum principalmente pera novos programadores receber uma tarefa e sair escrevendo código para resolver aquele problema, e muitos acreditam que uma vez resolvido ele não precisa mais de revisão, esse é o maior engano. Um bom software envelhece bem, não se torna obsoleto e sim, vai ganhando recursos e funcionalidades a medida que a corporação ou os usuários passam a necessitar de mais dados ou uma mudança de paradigma obrigue a alguma modificação.
A idéia por tras dos principios do CLEAN CODE é justamente criar métodos para resolver ou mitigar esse problema, tornando o desenvolvimento e a manutenção cada vez mais simples e mais ágeis e para isso ele usa basicamente 7 métodos ou regras.
“ Aprender a criar códigos limpos é uma tarefa árdua e requer mais do que o simples conhecimento dos princípios e padrões. Você deve suar a camisa; praticar sozinho e ver que cometeu erros; assistir os outros praticarem e errarem; vê-los tropeçar e refazer seus passos; Vê-los agonizar para tomar decisões e o preço que pagarão por as terem tomado da maneira errada.” – Robert C. Martin, Código Limpo – Habilidades préticas do Agile Software
Engana-se quem pensa que a limpeza de código é algo complexo! Trocar o nome de uma variável por um melhor, converter funções grandes que fazem várias coisas para funções pequenas que fazem uma única tarefa, diminuir a complexidade do código reduzindo as regras condicionais que ele possui, eliminar código duplicado e etc… Essas são algumas das coisas que podemos fazer para aplicar o conceito de clean code em nossos códigos.
Como Funciona
O pré-requisito de um programador é ter uma boa lógica, além de ter uma noção de como um computador funciona e noções de matemática e cálculo. Portanto, se você quer se tornar um bom profissional, desenvolva muito bem esses itens, principalmente a lógica. Portanto, não queira aprender uma linguagem específica (qualquer que seja ela) sem antes ter desenvolvido muito bem esses requisitos anteriores.
O clean code não é nada mais que uma filosofia, que pode e deve ser aplicada indiferente da linguagem ou tecnologia ser utilizada, onde regras de codificação são utilizadas e seguidas por todos, vamos ver cada uma dessas regras e algumas ferramentas ou mesmo exemplos que podem te ajudar a utilizar e entender essa regra e como você pode definir as regras para o seu proprio projeto e ir sugerindo melhorias em sua equipe.
O conjunto de regras, deve estar disponível a todos os integrantes da equipe, seja em um manual impresso, em um arquivo dentro do projeto, em documentos eletrônicos ou onde quer que você queira, desde que disponível sempre que alguém precisar dele, seja para uma consulta rápida ou para uma leitura integral. Deve ser claro e consiso além de especificar tudo. Este deve ser editado e corrigido na medida que for sendo necessário acrescentar alguma coisa porém alterações em regras vigentes devem ser desencorajadas.
1 – As regras para nomenclatura (regra do nome)
Indiferente do que você está nomeando no seu sistema, seja uma variavel, uma constante, uma função, um parametro, uma classe, um médoto, um tipo de dado complexo, um oujeto ou qualquer outra coisa, use nomes claros.
Tupo bem que o computador consegue entender o conteúdo da variavel indiferente do seu nome e se você criar qualquer coisa o seu código vai funcionar, porém, mesmo você daqui a alguns anos não vai se lembrar o que ela faz, pois nós humenos somos mais limitados nessa interpretação e associação, neste ponto as regras são basicamente o uso de um padrão consistente em todo o escopo do projeto.
Não existe uma regra para tudo, o que manda neste ponto é a consistencia, a regra deve especificar por exemplo um prefixo e/ou um sufixo, o uso de uma regra como camelCase ou snake_case ou qualquer outra variação específica, o uso do idioma, você pode por exemplo determinar que será usado o idioma nativo (portugues no nosso caso) ou o universal inglês ou outra regra a seu critério. Veja um exemplo:
CONSTANTES – Devem ser declaradas usando todas as letras maíusculas, em portugues e o prefixo determina seu uso, usando como separador o underscore (_) como no snake_case tendo um sufixo que determina suas variações. Ex: CONF_DATA_EXTENSO_FORMATO (prefixo CONF, determina uma configuração), (DATA_EXTENSO seu conteúdo, ou o que determina) (FORMATO, indica que é uma formatação)
VARIAVEIS – Devem ser usadas usando o formato da notação húngara, onde os prefixo indica o tipo, e o resto do nome indica o seu conteúdo, usando os nomes em portugues, com a notação CamelCase e sem sufixos. Es: $strNomeCompletoCliente (str indica o tipo String) e (NomeCompletoCliente indica o conteúdo.
2 – Deixar sempre melhor (Regra do Escoteiro)
Essa é uma regra importante, e muitas vezes deixada de lado, você precisa abrir um arquivo onde estão declaradas algumas funções como uma biblioteca, para fazer a edição ou alteração de uma função específica, e percorrendo o código encontrou um ponto, que não estava dentro de uma regra como a ausencia de uma documentação ou mesmo um erro de formatação ou nomenclatura, é sua obrigação corrigir mesmo que essa edição não esteja no escopo do que você precisa fazer.
Por exemplo, você estava fazendo uma edição do código para mudar o cálculo do digito verificador dos códigos de barras de balança de um modelo específico, e se deparou com uma ausencia de comentário de um parametro na função de leitura do peso de balanca, você deve fazer a correção e enviar um commit separado informando que fez uma adequação para atender a uma regra que possa ter sido alterada ou corrigir uma ausencia que tenha passado despercebida.
Em resumo, essa regra define que você deve deixar o código mais limpo do que antes de mexer nele.
3 – Seja o autor do seu código (começo-meio-fim)
O código é como uma história contada pelo programador, onde cada programador pode ter uma forma diferente de contar, e isso é uma realidade, o que não pode haver é a ausencia de uma parte, ou rodeios, em codificação, significa que todo os seus códigos devem ter inicio ou entradas, meio ou fazer algum processamento com essas entreadas e fim, produzindo saídas como resultados.
Uma das regras é fazer funções pequenas, e simples, ou seja, cada função deve ser usada para uma única ação sem sobrecargas e com o máximo de abstração possível, para poderem ser usadas da maneira geral e universal dentro do escopo do seu projeto.
4 – Não Seja Repetitivo (DRY – Don´t Repeat Youself)
Este principio se aplica a tudo, seja código, documentação, testes, bancos de dados ou qualquer outra parte, você deve ser o mais objetivo possível, ou seja, dois lugares diferentes não devem fazer a mesma coisa ou armezenar os mesmos dados ou mesmo explicar o óbvio.
O DRY diz que cada pedaço do conhecimento de um sistema deve ter uma representação única e ser totalmente livre de ambiguidades. Em outras palavras, define que não pode existir duas partes do programa que desempenhem a mesma função.
5 – Seja programador, não contador de histórias (regra dos comentários)
Os comentários devem ser feitos onde são necessários, e evoluirem com o código, não é necessario comentar cada linha de código, cada instrução ou bloco de introções. Quem vai ler o seu código fonte é possivelmente outro programador que tenha o mesmo nível que você ou até mesmo nível superior, portanto, não precisa explicar detalhes da construção da linguagem ou o que cada instrução está realizando.
Um outro aspecto a ser analisado, é não confundir comentário com documentação, muitas vezes podemos documentar uma função ou método ou classe no próprio código, usando blocos de comentário, isso não é errado, e deve ser encorajado.
6 – Tratamento de erros e excessões (regra da garantia)
Muitas coisas podem dar errado em tecnologia, e é dever do programador garantir que elas não quebrem ou causem inconvenientes para o sistema como um todo. Ou seja, se você esta desenvolvendo uma função simples ou um sistema complexo, você deve garantir que nenhuma parte possa causar efeitos colaterais.
Saber fazer o tratamento correto dos dados é uma tarefa importante e um dever do programador, não temos como garantir de antemão que um usuário ou mesmo um outro sistema ou API vai nos fornecer dados corretos, é nossa garantia fazer todas as validações necessárias e devolver excessões corretas que sejam úteis e garantam o perfeito funcionamento do resto.
Cada linguagem ou ferramenta ou framework tem uma forma diferente de lidar com excessões, cabe ao programador lidar com elas da menira correta e manter sempre uma correta documentação destas.
7 – Testes (regra da validação)
Todo e qualquer código por mais simples que seja, só é considerado limpo e utilizavel depois de terem sidos feitos testes e terem retornado valores válidos, sem causarem efeitos indesejados e colaterais.
Os testes também precisam ser validados e existem dezenas de técnicas para avaliar os resultados de sequencias de teste. Estes devem seguir alguns passos para serem considerados válidos, a seguir vamos falar sobre alguns deles.
Testes devem ser rápidos, podendo serem executados a qualquer momento, se você escreveu uma rotina de testes para um determinado bloco de código, este pode ser executado a qualquer momento sem causar prejuizo ao código ou ao sistema.
Independentes, um determinado teste não pode interferir de maneira nenhuma em outro ou no funcionamento do software como um todo, ou seja, não pode haver efeito cascata em uma sequencia de teste.
Repetivel, ou seja, os testes devem poder ser repetidos a qualquer momento, e resultarem no mesmo conjunto de resultados o que garante o seu funcionamento e o funcionamento mesmo em ambientes diferentes.
Objetivo, deve se retornar resultados simples como verdadeiro ou falso, para que a interpretação deste também seja objetiva. Se possivel, pense em testes antes de escrever o próprio código, de maneira a garantir que o código seja muito complexo para ser testado como um todo.
Por que utilizar
A produtividade de um programador está diretamente ligada a qualidade do código em que ele trabalha. Por isso, realizar a manutenção de um software é bem mais complicado do que desenvolver um do início.
É impossível escrever um código sem lê-lo, constantemente lemos código antigo quando estamos criando um novo, ou mesmo para a propria manutenção dele. Por isso, escrever um código que facilite a leitura é de suma importância. Se você quiser ser um programador melhor e mais produtivo, não há como escapar, comece escrevendo um código limpo.
Este pequeno fluxo acima é o funcionamento de um programador mediocre e infelizmente o padrão para a maioria das funções que envolvem um ambiente comercial, ser diferente disso é o objetivo de um bom programador, que queira se tornar cada dia melhor.
Código Ruim, pode ser causado por mudanças repentinas e constantes, cronogramas apertados, pressão por uma entrega mais rápida, começar do básico para depois evoluir, entre centenas de outras coisas porém, o principal motivo é a culpa do próprio programador. Todos os fatores citados neste paragrafo são a realidade de mais de 90% das empresas de software e não podem ser a justificativa para derrubar a qualidade do que você está fazendo.
Os gerentes e marqueteiros buscam em nós programadores as informações que precisam para fazer promessas e firmarem compromissos. Os usuários esperam que validemos as maneiras pelas quais os requisitos se encaixarão no sistema. Nossa cumplicidade no planejamento do projeto é tamanha que compartilhamos uma grande parcela da responsabilidade em caso de falhas; especialmente se estas forem em relação a um código ruim. A maioria dos agentes envolvidos sejam eles gerentes, usuários ou qualquer outro membro da equipe querem a verdade, mesmo que demonstrem o contrário, eles podem proteger com paixão o prazo e os requisitos, essa é a função deles. A sua é proteger o código com essa mesma paixão!
Colocando em Ação
O mais importante para que essa filosofia funcione é usar o bom senso, se você quer ter sucesso na melhoria da qualidade dos códigos produzidos pela sua equipe, não queira ser um ditador de regras ou um usar um fanatismo religioso por uma determinada filosofia, nem por uma linguagem ou ferramenta tornando-a o cinjunto universal da salvação dos developers do mundo.
Neste sentido, a regra de ouro é SEJA PRAGMÁTICO, um programador pragmático é um preguiçoso por natureza e faz de tudo para manter-se assim, vivendo o momento presente, prestando atenção a suas tarefas e fazendo de tudo para automatiza-las e ganhar tempo.
Não re-invente a roda, apoie-se em regras e tecnicas apoiadas e aprovadas pelas comunidades de desenvolvedores, elas já foram amplamente testadas e possuem vastas documentações criadas e desenvolvidas por outros usuários para darem suporte aos seus usos nos mais variados níveis. E dentre as soluções existentes, sempre adote, aquelas que economizam digitação, favorecem a simplicidade e aumentam a expressividade.
Programadores em geral, sofrem da sindrome da memória curta, ou seja, se esquecem de algo que eles mesmos desenvolveram a alguns dias atras, portanto, tenha em mente que um código limpo, bem documentado e fácil de lêr, com um bom histórico de modificações e versionamento vão aumentar sua produtividade.
Tente ter uma visão panorâmica do todo, estudando a forma como as diversas linguagens e ferramentas lidam com o mesmo problema, ao ver o mesmo problema de vários ângulos diferentes, consegue-se ter uma visão melhor de como resolvê-lo e o que pode ser aplicado a determinadas práticas.
Não se foque somente nos aspectos técnicos, foque também em técnicas de melhoria e boas práticas, que possam motivar a equipe e gerar resultados palpaveis em pouco tempo. Ao adotar esse processo de evolução gradual, de melhoria contínua sobre seu próprio método de trabalho, com o tempo se torna um profissional ou equipe de extrema produtividade e eficacia.
Não confundir as coisas
Muitos conceitos são implementados e mesmo ensinados de maneira errada, ou, são aplicados e usados de maneira errada justamente por profissionais ruins que querem mostrar que estão fazendo algo para agregar um valor, porém intimamente não querem mudar a mente e realmente se abrirem para novas tendências e evoluções.
O que fazer quando um cliente chega a nós com uma maneira confusa de operação, garantindo que não há lógica naquela função e que, a qualquer momento, tudo pode mudar e ainda que ele tem a possibilidade de editar um dado como quiser? Muitas vezes, para nós, isso pode ser uma brecha de segurança ou até mesmo uma dificuldade para apresentá-lo de forma clara no sistema, cabe a nós usar ou aprender novos padrões para aplicar aquela solução de maneira viável.
Muitos líderes de equipe tendem a ver seu projeto como um filho e acabam super protegento sua criação. Evitando ao méximo qualquer modificação ou criando ferramentas que dificultem qualquer coisa voltado a isso, para melhorar a confiabilidade de sua aplicação, fazer um CODE REVIEW ou revisão deveria ser sempre bem vinda.
Muitas das técnicas de CLEAN CODE partem de principios de METODOLOGIAS ÁGEIS DE DESENVOLVIMENTO e não é incomum ver equipes inteiras fazendo as coisas pela metade ou de maneira errada pois usam ou distorcem as regras para adequar a sua realidade, onde o correto é adequar o seu código e as suas metodologias as padrões existentes e amplamente utilizados.
A grande verdade é que vai fazer pouca diferença se você seguir os melhores padrões de codificação e arquitetura de software se a sua equipe não se interessar também. Não adianta ser um escoteiro, muito menos um caçador de código feio se você estiver sozinho nessa.
A gente pensa que quanto mais rápido nós programadores escrevermos código, melhor, porque aí mais coisas vão ser entregues, correto? Errado!
A triste realidade é que na verdade, quanto mais rápido nos lermos um código, mais coisas vão ser entregues. Você vai gastar 99% do seu tempo lendo o texto, palavra a palavra, e vai gastar 1% pra consertar o erro. Isso se você encontrar o erro de primeira. Então, a proporção é clara: você escreve o código uma vez, mas várias pessoas vão precisar ler esse código, repetidamente, até quando estiverem implementando outras coisas não relacionadas.
Cuidados
Tome cuidado com as CONVENÇÕES DE CÓDIGOS e NOMENCLATURAS ou você pode acabar em discussões sem fim sobre esses assuntos. Eu acrescentaria isso aquela listinha básica de coisas que não são discutíveis, meus avós já diziam que futebol, politica, religião e sexo não devem ser discutidas pois cada um tem o seus gostos. Acrescente a essa lista as convenções de código e nomenclaturas.
Deixe a decisão para os profissionais que tem essa competência, ou para os líderes e gestores da empresa, essas regras são quase como doutrinas, elas simplesmente tem que ser seguidas e não cabe a todos os membros discussões sobre qual é melhor ou pior, já que partimos do pré suposto que qualquer uma é melhor que nenhuma.
Não adianta ir de uma equipe sem nenhuma regra, para uma que use as regras mais rígidas sem um tempo para que todos se adequem, não é algo tão simples e envolvem não só aspectos técnicos como também costumes dos profissionais. Portanto, começe por coisas simples, e vá acrescentando regras ou recomendações gradualmente até que toda a equipe tenha maturidade suficiente e entendimento para ver os beneficios a curtos, médios e longos prazos.
Então antes de entrar nesse bonde com o time inteiro, eu com certeza definiria alguns “orçamentos de tempo”, ou alguém com um voto de minerva. Digo isso porque diante de tanta informação que que vai ser levantada, alguma decisão vai ter que ser tomada para avançar, nem que seja um micro passo pra ver no que vai dar. Funcionou? Ótimo. Não funcionou, ninguém deve ficar bravo ou apontar dedos. Bora gastar esse tempo fazendo mais uma iteração.