O que eu aprendi com o Clean Code

Silvério Vale • 5 de outubro de 2021

Recentemente, li alguns artigos criticando o lendário Clean Code. Notei que, por mais que cada um possuísse uma dose de razão, todos erraram o alvo: atacaram regras isoladas e ignoraram os princípios e valores por trás delas.

Neste breve artigo, pretendo expor os pontos que considero fundamentais no Clean Code e como penso que ele deva ser aplicado.

Clean Code é sobre valores, não regras

Apesar de apresentar listas de regras, o autor deixa claro que a mensagem central do livro não está nelas:

"O sistema de valores tem sido o objetivo e o assunto deste livro. Não se cria um código limpo seguindo uma série de regras." [1]

Mas, então, o que há no livro além das listas e exemplos de code smells?

Princípios, valores e ferramentas

Uncle Bob faz um bom trabalho quando divide o livro em três partes:

  • Princípios, padrões e práticas do Clean Code;
  • Estudos de caso;
  • Lista de heurísticas e code smells.

Não há nada de errado com esta divisão. Vou apenas fazer uma distinção complementar. O conteúdo do livro pode ser separado em:

  • Princípios, padrões e valores que norteiam o Clean Code;
  • Um enorme número de "ferramentas" que permitem alcançar esses princípios e valores na prática;
  • Exemplos bons e ruins para ilustrar os itens anteriores.

Com "ferramentas" não me refiro a frameworks ou bibliotecas, mas sim a padrões de desenvolvimento. Por que, então, escrevi "ferramentas" em primeiro lugar? Pois gosto de pensar nas soluções apresentadas como "ferramentas" para a caixa do desenvolvedor (ou artesão - se preferir). Ferramentas que estes podem utilizar e adaptar conforme julgarem necessário, com base na sua experiência e na situação concreta de cada desafio.

Essas ferramentas são extremamente úteis, mas perdem o sentido quando separadas dos valores e princípios que as justificam.

A mensagem central e as principais lições

No meu entendimento, a principal mensagem poderia ser resumida como: a legibilidade do código é (muito) importante - esforce-se para melhorá-la.

O código é como um livro

Talvez essa comparação já tenha sido feita antes, mas isso não a torna menos importante. Se reconhecemos os atributos de uma boa leitura e tentamos aplicá-los ao nosso código, começamos com o pé direito.

Diferentes níveis de abstração

Nesse sentido, uma das características que tornam os livros agradáveis de serem lidos é a separação do conteúdo em diferentes níveis de abstração e a apresentação gradual deste conteúdo.

No clássico "Como Ler Livros", Mortimer Adler recomenda uma sondagem inicial, prévia à primeira leitura, para se obter uma noção geral do que será lido. Ainda, Adler sugere que os leitores não fiquem "travados" tentando decifrar trechos não compreendidos, mas que sigam em frente e retornem a esses trechos depois de terem concluído a obra.

O motivo dessas recomendações parece ser o mesmo: Uma visão geral do todo facilita a compreensão das partes isoladas, e também permite que você decida se vai ou não ler aquilo.

Trazendo essa perspectiva para o código, entendemos que este deva ser apresentado gradualmente, começando pelos níveis de abstração mais altos e seguindo aos poucos para os detalhes.

Desta forma, o leitor consegue adquirir uma visão do todo antes de encarar as minúcias - facilitando a compreensão destas. Ainda, permite que ele decida se precisa ou não saber daqueles detalhes naquele momento.

Para exemplificar, suponha que você precise corrigir um bug no envio de e-mails para os novos usuários criados. Se você acessar o serviço de criação de usuários e notar que ele consome métodos como verificarUsuarioDuplicado, adicionarUsuarioAoGrupo, validarEndereco, muito provavelmente você irá passar direto por essas chamadas e seguirá para o momento do envio de e-mail.

Porém, imagine este outro cenário: você olha para o código do serviço e toda a lógica de verificação de duplicação, de adição a grupos e validação de endereços está emaranhada com a de envio de e-mail. Além de ser mais confuso, você será obrigado a ler e entender aquilo tudo, sendo que você está interessado apenas no envio de e-mail.

Obviamente, a primeira experiência é muito superior à segunda.

O código é a principal documentação

O código é a melhor e mais atualizada documentação do sistema. Todos os demais artefatos, cedo ou tarde, ficam desatualizados. O time também pode mudar e não se pode depender do conhecimento acumulado na cabeça dos membros. Portanto, para entender o que o código faz, a fonte primária de informação é o próprio código.

E você, prefere que a sua documentação seja agradável como um conto que se desenrola aos poucos, ou árida como um manual de instruções, cheio de códigos a serem decifrados, mesmo para as tarefas mais básicas?

Nomenclatura e organização

Uma vez, me deparei com o erro "5C" (ou algo do tipo) no visor da minha máquina de lavar roupas. Após vários minutos consultando o manual, descobri que aquilo significava que a máquina estava com muita espuma e bastava aguardar até que o ciclo voltasse ao normal.

Aqueles minutos poderiam ter sido salvos caso a máquina apresentasse em seu visor a mensagem: "Muita espuma. Aguarde."

Obviamente, uma máquina de lavar possui uma forte restrição de número de caracteres no visor. Mas o seu código não!

Quando se trata de desenvolvimento Web e Mobile, com raras exceções, o tamanho do nome das variáveis e funções é irrelevante do ponto de vista de performance e armazenamento. Portanto, é muito preferível lançar uma FoamLimitExceededException do que uma 5Ce.

Essa questão começa invadir a área de conselhos práticos, porém merece ser mencionada pois, como escreveu o autor: "Nomes são responsáveis por 90% da legibilidade do software." [2]

No mesmo sentido, a organização do código é importante. Tanto a organização do projeto em sua estrutura de pastas e arquivos quanto a organização do código em si.

A obra apresenta diversas sugestões sobre como fazer isso, bem como vários bad smells que devem ser evitados. Contudo, deve-se ter em mente que o objetivo é o mesmo: melhorar a legibilidade do código.

Com o devido respeito, não estou interessado no número de linhas que Uncle Bob diz que uma função deve ter. Minha abordagem é a seguinte: Vou escrever a função da forma mais legível e compreensível que eu conseguir. Para isso, posso (e vou) utilizar sugestões que encontrei no Clean Code.

Testes e Refatoração

Um tópico recorrentemente mencionado é o de testes automatizados. Eles podem até parecer não estar relacionados ao código limpo, porém, na maior parte das vezes, eles viabilizam o código limpo.

E aqui entra outro ponto importantíssimo que aprendi com o livro: O Código Limpo não é algo alcançado de uma só vez, por um arquiteto sênior que se senta por algumas horas e escreve um documento de padrões para o sistema. Não...

O código limpo está diretamente relacionado à refatoração - outro aspecto chave que é recorrentemente abordado. Cedo ou tarde, o código se suja. O que difere um sistema "limpo" de um "sujo", é que, no primeiro, existe um constante esforço de "limpeza".

E, aqui, refatoração e testes automatizados se unem a favor do Clean Code: Essa "limpeza", que também poderia ser encarada como melhoria, é realizada por meio da refatoração constante. E essa refatoração só pode ocorrer de forma ágil e segura se existir um conjunto de testes automatizados que possam ser executados após qualquer alteração para garantir que o funcionamento do sistema não foi prejudicado.

Conclusão

Eu diria que o Clean Code não se trata de uma lista de regras e sequer expõe um estado de "limpeza" perfeito que deva ser alcançado. Ele apresenta um processo contínuo, que deve fazer parte da operação de qualquer time de desenvolvimento durante toda a "vida" do sistema.

As sugestões e os exemplos de bad smells estão lá e são, de fato, muito úteis. Porém, não devem ser encarados como receitas de bolo, mas sim como um compartilhamento de experiência de desenvolvedores de enorme senioridade. Eles, provavelmente, já passaram por situações semelhantes à sua e encontraram soluções elegantes para desafios semelhantes aos seus.

"Há uma série de práticas simples que possam substituir a experiência? Obviamente que não. Por outro lado, as práticas descritas neste capítulo e neste livro são uma forma consolidada de muitas décadas de experiência adquiridas pelos autores." [3]

Portanto, não se incomode caso alguma sugestão do Clean Code não se encaixe bem no seu contexto. Nem pense que a obra perdeu seu valor por causa disso. Entenda a mensagem principal e utilize - com sabedoria e conforme a necessidade - as "ferramentas" que você adquiriu nesta grande obra.



Referências:

[1] Martin, Robert C. Código Limpo. Pág. 304.

[2] Martin, Robert C. Código Limpo. Pág. 309. Texto original: "Nomes em softwares são 90% responsáveis pela legibilidade do software."

[3] Martin, Robert C. Código Limpo. Pág. 176.

© 2023 Cartas de um Dev. Todos os Direitos Reservados.