Como tema de seu projeto do Bluesoft Labs, Bruno Lui leu o livro Clean Code, fez duas apresentações e escreveu o artigo que segue. Foi notável a diferença que a leitura deste livro fez em seu dia-a-dia, transformando não somente sua forma de escrever software mas também a de todos os outros membros da equipe que foram, no bom sentido, contaminados pelo Clean Code.
Gostaria de destacar que assistir a apresentação e ler a este artigo não substitui de forma alguma a riquíssima experiência da leitura desse livro, leitura que recomendados a todos os desenvolvedores que buscam tornarem-se melhores. O livro está disponível para venda em português e inglês.
Confira os videos e os slides no final do post.

O primeiro objetivo dos desenvolvedores quando criam uma funcionalidade é fazê-la funcionar. Tudo bem, está funcionando, mas e o código, como esta? Será que o código que faz tudo funcionar está legível, fácil de ser entendido, ou seja, será que está limpo?
  É preciso preocupar-se com o código, garantir que  está legível e bem escrito, pois somente o próprio código pode dizer de forma confiável o que o software realmente faz.
No livro Clean code escrito por Robert C. Martin, conhecido na comunidade de desenvolvimento de software como Uncle Bob, pode se encontrar várias técnicas e boas práticas para que se aprenda a melhorar a forma que se escrever código e deixá-lo mais limpo e claro. O livro ensina também a identificar um código ruim e melhorá-lo.
Mas afinal, o que é código limpo?

Robert fez esta pergunta a grandes desenvolvedores com bastante experiência no assunto como Dave Thomas, Michael Feathers, Ron Jeffries entre outros,  em suma, eles responderam que um código limpo deve ser:
  • Elegante (distinto)
  • Eficiente
  • Legível
  • Simples
  • Direto
  • Único, sem duplicidades
  • Bem escrito
  • Deve ser escrito cuidadosamente
  • E deve sempre possuir UMA responsabilidade

O código é importante e deve agregar valor ao negócio. Somente um código limpo pode oferecer a qualidade e entendimento que esperamos quando abrimos uma classe. Portanto é necessário que seu código seja limpo e legível para que qualquer um que encontrá-lo possa facilmente entendê-lo evitando perda de tempo e facilitando o trabalho de todos.
Cada capítulo do livro aborda um aspecto diferente da codificação, e ao passo se lê, as coisas vão se complementando e é possível notar que tudo tem seu jeito “limpo e claro” de ser feito. A seguir exploraremos um pouco do que Uncle Bob nos ensina.

Nomes significativos

Vamos começar pelos nomes. Escolhemos nomes para tudo, desde variáveis até métodos e classes, por causa disso devemos escolhê-los bem.
Os nomes devem nos dizer três coisas: Porque existem, o que fazem e como são usados. Devem revelar sua intenção e ser significativos, devem dizer o que estão fazendo e o que significam.

Faça distinções significativas, use nomes diferentes dentro de um mesmo escopo. Nomes como a1, a2, a3 são o oposto de nomes que demonstram intenção. São confusos e não informam nada. Evite também usar abreviações ou trocadilhos, escreva exatamente o que você quer dizer, o nome deve ser auto-explicativo. É comprovado que um desenvolvedor passa muito mais tempo lendo código do que escrevendo, por isso não se preocupe em economizar caracteres ao escolher um nome, o fato de um ser claro e objetivo poupará muito mais tempo do futuro do que os caracteres a menos que você digitar ao escolher um nome curto e ruim.

Métodos e funções

O que os tornam métodos e funções fáceis de se ler e entender? A primeira regra dos métodos é que eles devem ser pequenos, a segunda é que eles devem ser menores ainda.

Métodos devem conter no máximo 20 linhas e seu nível de identação não pode ser maior que dois. Quanto ao conteúdo, um método deve ter somente UMA responsabilidade. É difícil dizer o que é “uma responsabilidade”, mas uma maneira de descobrir se um método está fazendo mais de uma coisa, é tentar extrair uma parte dele em outro método. Se for possível, realmente o primeiro método tinha mais de uma responsabilidade.
Evite passar muitos parâmetros para um método, porque isso pode causar confusão além de dificultar a escrita de testes unitários, pois assegurar que todas as combinações de parâmetros diferentes funcionarão é bem mais trabalhoso. Passar parâmetros booleanos (verdadeiro ou falso) também não é uma boa prática, além complicar a assinatura do método, claramente a função tem mais de uma responsabilidade. Outro detalhe importante  que devemos nos preocupar são os efeitos colaterais, esses efeitos são mentiras. Seu método diz que fará uma coisa, mas faz outras “escondidas”.

Observe o método abaixo:
public boolean checkPassword(String username, String password) {
     String passwordStatus = cryptographer.decrypt(password);
     if(passwordStatus.equals(“OK”)) {
          Session.initialize();
          return true;
     }
     return false;
}
O método checkPassword tem o objetivo de verificar a validade da senha, mas além disso está abrindo um sessão, o que não está coerente com a finalidade do método. Não se esqueça, seu método deve sempre ter somente um objetivo.

Comentários

Comentários podem ser úteis se colocados nos lugares certos, mas também podem ser mentirosos e trazer desinformação. Na verdade, o melhor comentário é aquele que não precisa ser escrito. Podemos usá-los de forma benéfica para informar o leitor de alguma conseqüência ou fornecer a intenção de uma decisão tomada, mas um dos principais motivos para você escrever um comentário é porque o código está difícil de ser entendido. Você acha que o código ficou meio confuso e acha melhor adicionar um comentário? Não, você acha melhor refatorar!
Quando você pensa em adicionar um comentário em seu código, é um forte indício que ele não está muito bom, não está claro.
Não use comentários quando você pode usar métodos ou variáveis, explique-se no código, lembre-se que apenas o código pode dizer o que ele realmente faz.

Formatação

A formatação do código é importante, pois se trata da forma de comunicação do desenvolvedor, um código todo bagunçado e sem formatação dificulta o entendimento de quem o está lendo.
A legibilidade do código terá profundo efeito sobre todas as mudanças que serão feitas, seu estilo e disciplina sobrevive sobre estas mudanças.
Procure escrever  classes com no máximo 500 linhas, classes menores são mais fáceis de se entender. Já para as linhas de código, tente estabelecer um limite de caracteres por linha. Uma boa identação ajuda a visualizar melhor todo o escopo e facilita a identificação de situações e regras relevantes. Tente manter conceitos relacionados mais próximos verticalmente, para criar um fluxo na leitura do código. Use espaços entre operadores, parâmetros e vírgulas. Evite deixar o código todo grudado.

Tratamento de erros

Quando estamos programando devemos tratar os possíveis erros que nossa aplicação poderá lançar, as coisas podem dar errado e temos que estar certos que nosso código fará o que deve fazer.

Prefira lançar uma exception ao invés de retornar um código de erro, estes retornos desorganizam a chamada do método e pode-se facilmente esquecer de verificá-los.

Defina o fluxo do método separando as regras de negócio de erros ou outras situações. Para seus erros crie mensagens informativas, mencionando a operação que falhou e o tipo de falha.

Testes unitários

Há alguns anos atrás, pouco se ouvia falar de TDD (Test Driven Development). Para muitos TDD erá apenas trechos de código que garantia que o programa “funcionasse”. Mas essa idéia amadureceu bastante entre todos nós, hoje em dia programar com TDD é um conceito de alto nível, por isso, todos os testes que criamos devem ser escritos com código limpo.

Queremos dizer muito em nossos testes, por isso que eles devem ser legíveis, claros e simples de entender. Um teste com código ruim e difícil de entender é muito mais trabalhoso para se dar manutenção. Cada teste deve possuir apenas um conceito para facilitar seu entendimento, também deve sofrer alterações da mesma maneira que o código que está testando, tudo isso para manter a flexibilidade e a manutenabilidade do código.
Lembre-se que o código do teste é tão importante quanto o código da produção.
Todos sabem que o TDD nos manda escrever o teste antes do código de produção em si, considere essas três regras do TDD:
  1. Você não pode escrever o código até que você tenha criado um teste que falhe.
  2. Você não pode escrever mais testes do que seja suficiente para falhar.
  3. Você não pode escrever mais código do que o suficiente para passar o teste que está falhando.
Se você conseguir seguir essas regras ao desenvolver, você estará praticando TDD corretamente.

Classes

Para começarmos a falar de classes limpas podemos partir da organização das classes. De acordo com os padrões Java, uma classe deve começar com uma lista de variáveis de preferência nesta ordem:
  1. variáveis publicas e estáticas
  2. variáveis privadas e estáticas
  3. variáveis privadas

Depois das variáveis vêm os métodos públicos. Os métodos privados aparecem depois de suas chamadas. Assim como os métodos, as classes também devem ser pequenas. Ninguém gosta de encontrar classes gigantes onde é difícil até mesmo de se encontrar dentro delas. Mas a pergunta é: O quão pequenas elas devem ser?
O nome da classe deve representar a sua responsabilidade. Tentar fazer uma breve descrição da classe, explicando o que ela faz pode ajudar a escolher o nome certo. Esta descrição deve ter no máximo 25 palavras e não  conter palavras como “mas”, “e”, ”ou”, “se”, pois expressam mais de uma coisa mostrando que há mais de uma responsabilidade.

Outra maneira de descobrir o tamanho ideal da classe é analisarmos suas responsabilidades. O Princípio da Única Responsabilidade (Single Responsibility Principle) diz que uma classe deve ter uma, e apenas uma razão para mudar. Quando uma classe possui mais que um motivo para ser alterada é porque provavelmente ela esta fazendo mais coisas do que devia, ou seja, ela têm mais de um objetivo. O princípio nos dá definições de responsabilidade e uma diretriz para o tamanho de uma classe. Tentar identificar responsabilidades nos ajuda a melhorar nosso código e criar melhores abstrações.

Para concluir, queremos nosso sistema com pequenas classes, cada uma com uma única responsabilidade, tendo uma razão para mudar e colaborando com outras para alcançar o comportamento desejado do sistema.

Design emergente

Design emergente é um design que nunca é o final, sempre está em evolução. Para conseguirmos criar boas estruturas de código tornando mais fácil de aplicar princípios como SRP e DIP, e assim facilitar a criação de um de bom design de software, Kent Beck estipulou 4 regras para um design simples (Simple Design):

1. Rode todos os testes

Fazer um sistema testável nos obriga e usar boas práticas como classes e métodos pequenos de apenas uma responsabilidade.
Quanto mais testes fazemos mais e melhores maneiras e princípios seguiremos para evitar o acoplamento de nosso código. Lembre-se, um sistema testável possui sempre todos os seus testes passando. Um sistema que não é testável, não é verificável e assim não pode ser entregue para produção.

2. Remova duplicação

Duplicação é o primeiro inimigo de um bom design, ela representa trabalho e riscos adicionais além de uma maior e desnecessária complexidade. Ela se manifesta em linhas de códigos iguais ou parecidas além de aparecerem nas implementações. Usar padrões como Template Method é uma saída para remover duplicações mais complexas.

3. Expresse sua intenção

Escrever código que nós entendemos é fácil pois estamos concentrados e ligados no problema que estamos tentando resolver. Mas o próximo que pegar o código para fazer manutenção, não estará tão ligado ao problema como você estava quando implementou a solução.
Expressar-se bem no código pode trazer grandes benefícios para o desenvolvimento de um sistema. Além de poupar tempo de quem o mantém. Você pode expressar-se bem em seu código escolhendo bons nomes, deixando métodos e classes pequenas, separando responsabilidades. Lembre-se que você pode sem o próximo a ler este código.

4. Diminua o número de classes e métodos

Sempre que possível, nosso objetivo é manter sistemas pequenos enquanto ao mesmo tempo se mantém  métodos e classes pequenas.
Princípios e boas práticas não substituem a experiência, mas a partir delas pode se dar o primeiro passo para desenvolver um bom design.

Conclusão

Ao longo da leitura do livro, comecei a sentir a diferença que ele estava fazendo em meu desempenho no trabalho, em meu dia-a-dia. Passei a pensar de forma mais limpa, clara e objetiva ao escrever código, e automaticamente comecei a transformar os erros e “sujeiras” que antes faria em código eficiente e legível. Para tudo que vou fazer, penso duas vezes antes de implementar, pois minha consciência não me deixa mais largar um código ruim para trás.
Vivo me perguntando:
  • Os nomes dos métodos e variáveis estão coerentes?
  • Cada método possui sua responsabilidade?
  • Não dá pra extrair para outro método?
  • Está simples e fácil de entender?
Essas são  perguntas que você deve se fazer enquanto programa. Inconscientemente elas sempre surgiram quando você aprender as boas práticas do clean code. As técnicas e idéias transmitidas no livro são muito válidas para todo desenvolvedor que se preocupa com a qualidade de seu código. Se você que aprender a escrever código limpo, ai está um ótimo livro para começar.
Autor

André Faria Gomes é executivo, empreendedor, investidor, mentor, gerente, escritor, palestrante, podcaster e agilista. Atualmente, é CEO da Bluesoft em São Paulo, investidor e membro do conselho da Wow e mentor da Liga Ventures.

8 Comentários

  1. Pingback: Lista com todas as Práticas Ágeis | André Faria Gomes

  2. Pingback: Uncle Bob Martin, um grande exemplo para nós Desenvolvedores | André Faria Gomes

  3. Bastante interessante a resenha que fizestes. Gostaria de saber se você adquiriu o livro em Inglês ou Português. Se foi em Português, como está a qualidade em linhas gerais (Tradução, Coesão, etc)? Tenho esta dúvida, porquê se em Português está mais barato e chega com maior agilidade que comprar no Amazon.
    Obrigado!

    • Olá Gustavo.
      Obrigado pelo seu feedback. O livro que temos aqui na Bluesoft é em inglês, nós o trouxemos dos Estados Unidos, por isso, infelizmente, não podemos afirmar se a qualidade da tradução para o português é boa ou não é.

  4. Muito útil e informativo. Manutenções em sistemas que seguem esses princípios deixariam de ser traumatizantes.

  5. Excelente resenha e apresentação, Bruno! Precisamos de mais exemplos como o seu. Cada vez mais desenvolvedores precisam conhecer, ler e praticar as técnicas e dicas do Uncle Bob. No meu blog escrevi já há algum tempo dando essa dica de livro e de dois outros clássicos. Vide em http://josepaulopapo.blogspot.com/2009/01/codigo-limpo-beneficios.html
    Também indiquei e falei sobre a sua resenha em meu twitter: http://twitter.com/josepapo/status/13499117833
    http://twitter.com/josepapo/status/13499207736
    http://twitter.com/josepapo/status/13499293240

Deixe aqui o seu comentário