É bem conhecido que eu prefiro código que tenha poucos comentários. Eu codifico pelo princípio de que um bom código não requer muitos comentários. Na verdade, muitas vezes eu sugeri que cada comentário representa uma falha para tornar o código autoexplicativo. Eu aconselhei programadores a considerar comentários como um último recurso.
Recentemente, eu fiz uso deste último recurso.
Eu estava trabalhando com um membro da nossa equipe cleancoders.com em uma questão específica com o nosso site. Estávamos tentando implementar um recurso que informaria a um cliente que comprou um de nossos vídeos quais outros vídeos ele poderia querer comprar também. O recurso iria encontrar todos os vídeos que tinham sido comprados por outros clientes que tinham comprado esse vídeo, e escolheria o mais popular e o recomendaria ao cliente.
O algoritmo para fazer isso pode levar vários segundos para ser executado, e nós não queremos que o cliente tenha que esperar. Portanto, decidimos armazenar em cache o resultado e executar a função não mais do que a cada N minutos.
Nossa estratégia era envolver a função de execução longa em outra função que retornaria o resultado anterior do cache e, se mais do que N minutos tivessem passado, executaria o algoritmo em uma thread separada e colocaria em cache o novo resultado. Chamamos isso de “choking”.
A função de execução longa foi chamada de “Função Chokeable” e a função de envolvimento foi chamada de “Função Choked”. A Função Choked tinha a mesma assinatura e valor de retorno que a função Chokeable, mas implementou o nosso comportamento de choking.
Tentar explicar isso em forma de código é muito difícil. Então, escrevemos o seguinte comentário no início do módulo de choking:
; Uma função Choked é uma forma de acelerar a execução de um ; algoritmo de longa duração – a então chamada "Função Chokeable". A função Choked ; retorna o último resultado da Função Chokeable; e só permite que ; a função Chokeable seja chamada se mais do que o tempo de Choke tiver ; decorrido desde a sua última invocação.
Agora imagine os testes unitários! No começo, quando estávamos escrevendo-os, tentamos nomear esses testes com bons nomes longos. Mas os nomes ficavam cada vez mais longos e obscuros. Além disso, à medida que tentávamos explicar os testes uns aos outros, descobrimos que precisávamos recorrer a diagramas e imagens.
No final, desenhamos um diagrama de tempo que mostrava todas as condições com que teríamos de lidar nos testes unitários.
Percebemos que ninguém mais iria entender nossos testes, a menos que eles pudessem ver esse diagrama também. Então, desenhamos esse diagrama de tempo, juntamente com o texto explicativo, nos comentários no módulo de teste.
; Abaixo está o diagrama de tempo para como as Funções Choked são testadas. ; (Veja o módulo função-choke para uma descrição de Funções Choked.) ; ; A primeira linha do diagrama de tempo representa chamadas para a ; função chokek. Cada chamada é também objeto de um teste unitário; então eles ; são identificados por um teste# ; ; Nesse teste, a função chokeable conta o número de vezes que ; foi invocado, e a função choked retorna esse contador. O esperado ; valor de retorno é o abaixo da primeira linha horizontal no ; diagrama de tempo. ; 1 2 3 3.5 4 5 6 Test# ; aaaaa ;--------------------------- ; n n 1 1 1 1 2 ;--------------------------------------------- ;AAAAA AAAAA ; CCCCCCC CCCCCCC ; ; Where: A is the algorithm time. (The chokeable function run time) ; C is the choke time ; n is nil ; 1 is "result-1" ; 2 is "result-2"
Os nomes dos testes passaram a ser, simplesmente, test1 e test2, até test6; voltando ao diagrama.
Ficamos bastante satisfeitos com o resultado – tanto o código como os comentários.
Então, este é um daqueles casos em que não havia nenhuma boa maneira de o código ser autodocumentado. Se tivéssemos deixado os comentários fora desses módulos, teríamos perdido a intenção e o raciocínio por trás do que fizemos.
Isso não acontece o tempo todo. Na verdade, eu achei esse tipo de coisa relativamente rara. Mas de fato acontece e, quando acontece, nada pode ser mais útil do que um comentário bem escrito, bem pensado.
***
Uncle Bob faz parte do time de colunistas internacionais do iMasters. A tradução do artigo é feita pela redação iMasters, com autorização do autor, e você pode acompanhar o artigo em inglês no link: http://blog.cleancoder.com/uncle-bob/2017/02/23/NecessaryComments.html.