Clean Code

 Rafael Paz
Clean Code (Código Limpo)
Enquete
• Quem se preocupa com o código que produz?
• Onde vocês trabalham, há algo relacionado a
  manter o código limpo?
• Quem realiza testes do seu código?
• Quem pratica TDD?
O que é código limpo?

•   Código bem escrito
•   Legível
•   Elegante
•   Cuidadoso
•   Sem duplicações
•   Fácil manutenção
Tempo de desenvolvimento x Tempo
          da aplicação
Porque escreveu um código sujo?
• Estava com pressa..
• Meu gerente quer que o código funcione..
• Muita coisa pra terminar e o tempo é curto!


 Quando a sujeira aumenta, a produtividade da
  equipe diminui! O tempo economizado no
   desenvolvimento é utilizado em dobro na
                 manutenção.
Objetivo de escrever um código limpo?
•   Produzir um código melhor
•   Escrever código para humanos lerem
•   Reduzir a complexibilidade
•   Manter a manutenibilidade do código ao longo do tempo
•   Software não é só para o cliente, mas também para o
    desenvolvedor
Como saber se um código está sujo?
Nomes significativos
    Tanto as variáveis como as classes e métodos
      devem responder as seguintes perguntas:
 - Porque isso existe?
 - O que isso faz?
 - Como isso é usado?

O nome deve revelar exatamente o propósito

Se o nome requer um comentário, então não está
  revelando sua intenção
• Não faça isso:
 int d; // Tempo decorrido em dias

• Faça:
int tempoDecorridoEmDias;
int diasDesdeCriacao;
int diasDesdeModificacao;
• Faça distinções:

a1 ?
                     a2 ?
  int[] d ?
              d[0] = a1; ?

Nomes com apenas uma letra ou número são difíceis de serem
  entendidos e encontrados
public List<int[]> getLista{
  List<int[]> lista1 = new ArrayList<int[]>();
     for (int[] x : lista)
       if (x[0] == 4)
           lista1.add(x);
  return lista1;
}



public List<int[]> getCelulasSinalizadas{
  List<int[]> celulasSinalizadas = new ArrayList<int[]>();
     for (int[] celula : tabuleiro)
       if (celula[VALOR_STATUS] == SINALIZADA)
           celulasSinalizadas.add(celula);
  return celulasSinalizadas;
}
Podemos também refatorar

public List<Celula> getCelulasSinalizadas{
          List<Celula> celulasSinalizadas = new ArrayList<Celula>();
          for (Celula celula : tabuleiro)
                    if (celula.isSinalizada())
                               celulasSinalizadas.add(celula);
          return celulasSinalizadas;
}
Comentários
Se foi necessário comentar, o código não expressa o
                       que faz

 Desnecessário indicar o autor do método/classe,
          seu controle de versão faz isso

     Comentários não vão melhorar o código!

Mas... Comentários podem ser um mal necessário.
Comentários podem ser mentirosos
e trazer desinformação!



 Não recebem manutenção, quanto
mais velhos, maior a chance de estarem errados

        Comentários não vão esconder um código ruim.

  Quando pensar em comentar, é sinal que o código deve ser
                       refatorado
Comentários

    // check if the employee is elegible for benefits
if ((employee.flags == 100) && (employee.age > 65))


              Explique-se no código!


        if (employee.isElegibleForBenefits())
Comentários – Não faça!
//Obtém a idade atual da pessoa
  public int Pessoa.ObterIdadeAtual();



• -- Códigos antigos comentados
InputStreamResponse response = new InputStreamResponse();
response.setBody(formatter.getResultStream(),formatter.getByteCount());
// InputStream resultsStream = formatter.getResultStream();
// StreamReader reader = new StreamReader(resultsStream);
Comentários – Não faça
• Não comente para indicar fechamento de bloco:
                                 } // fim do else // fim do while

• Na forma html
• Javadocs não públicos
  /** The day of the month. */
  private int dayOfMonth;

  /**
  * Returns the day of the month.
  *
  * @return the day of the month.
  */
  public int getDayOfMonth() {
     return dayOfMonth;
  }
Comentários podem ser úteis
• API pública
• Avisos de consequência que um código pode
  causar
• Mostrar a intenção por trás de uma decisão, e
  não apenas para informação
Classes / Métodos
Devem ser pequenos!


 “A primeirA regrA dos métodos é que eles devem
     ser pequenos. A segunda regra é que eles
             devem ser menores AindA.”
                              Uncle Bob


Classes menores são mais fáceis de se compreender.
• Devem fazer apenas UMA coisa,
 e apenas isso




               Mas como identificar se o
                 método faz apenas uma
                    coisa?
Leia o que o método faz e tente
extrair um novo método
dentro dele.




Evite passar parâmetros booleanos, isso implica
  que o método faz mais de uma coisa
Quando escrevo um método, ele é feio, grande, cheio
  de if’s e loops. Há nomes pouco expressivos e
                       duplicação de código.




Depois eu refatoro meu método, extraio outros
 métodos (que fazem apenas uma coisa), troco
 nomes de variáveis e elimino a duplicação.
Parâmetros
• A quantidade ideal de parâmetros para um
  método/função é ZERO.
• Depois vem UM parâmetro, depois DOIS
  parâmetros.
• Evite um método com TRÊS parâmetros!
• Tenha um excelente motivo para métodos com
  mais de três parâmetros, mas em geral, não
  devem ser usados

• Quanto maior o número de parâmetros, mais
  difícil de entender o método

• Métodos com mais parâmetros são complicados
  para testar, pois possuem saídas diferentes.
Evite efeitos colaterais

public boolean checkPassword(String password){
  String passwordStatus = crypto.decrypt(password);
  if (passwordStatus.equals(“OK”)){
     Session.initialize();
     return true;
  }
  return false;
}
CQS – Command Query Separation

Métodos devem fazer algo ou retornar algo, mas
  não as duas coisas. Isso gera confusão, além
   de atribuir mais de uma responsabilidade.
DRY – Don’t Repeat Yourself

 Evite duplicidade no seu código,
preste atenção e reaproveite seus
           métodos.
SRP – Princípio da Responsabilidade Única

Esse princípio diz que deve existir um
 e somente UM MOTIVO para que uma
 classe mude

 Esse é um dos conceitos mais importantes em OO,
 identificar as responsabilidades e criar melhores
 abstrações.
Formatação

Formatar seu código é essencial, a legibilidade
 do seu código facilita mudanças e o entendimento.

                  Combine com sua equipe qual a
                indentação que será utilizada, para a
               leitura ser fácil entre todos os envolvidos.

Evite níveis de indentação maior que 2, o código fica
  mais fácil de compreender
Espaçamento



• De espaço entre operadores, parâmetros e
  vírgulas
Tratamento de erros

                 Tratar erros é
               responsabilidade do
               desenvolvedor, temos que
               garantir que nosso código
tem tratamento para os erros que podem
ocorrer.
Use exceptions ao invés de
retornar códigos de erro.

         Quem chama um método deve
  verificar se ocorreu um erro, mas isso
           pode ser esquecido.

    Forneça o contexto da exception, criando
  mensagens informativas sobre o que aconteceu,
  o que estava tentando fazer e por que o erro
  ocorreu.
Separe regras de negócio de erros ou outras
                    situações

try {
   MealExpenses expenses = expensesDao.getMeals();
   total += expenses.getTotal();
} catch (MealExceptionNotFound e) {
   total += expenses.getMealPerDiem();
}
Não retorne NULL, não passe NULL

Prefira retornar exceções,
objetos especiais ou coleções
vazias



   Tente evitar, pois sempre
corremos o risco de receber as
famosas NullPointerExceptions
TESTES

Pra testar o código eu perco muito tempo!




                       Verdade !
Mas não testar o código eu
  perco muito mais tempo
     do que se tivesse
         testado.
Use TDD

Com TDD você não vai escrever código enquanto
não tiver um teste falhando

Não vai escrever teste do que
o suficiente para falhar

Não vai escrever código a mais, afinal, seu teste
está passando, não preciso de mais código.
UM conceito por teste, não faça vários
       asserts em um mesmo teste, um assert
       por teste



O teste deve ser rápido e de fácil entendimento,
possuir respostas booleanas e sempre retornar o
mesmo resultado
Refatore seu Teste
• Tão importante quanto seu código, seu teste
  deve ser limpo constantemente.

• Quanto mais sujo o teste, mais difícil dar
  manutenção.

• Se deixar seus testes apodrecerem, seu código
  também apodrecerá
“todA linhA de código que você
escreve deve estar testada, e
         ponto finAl! ”
                   Uncle Bob
Maus Cheiros

 Se sentir que o código está com um "cheiro"
estranho, é um bom indício que deve limpa-lo




    Mas o que é mau cheiro em código?!
Maus Cheiros
• Comentários pobres, obsoletos e redundantes
• Código comentado
• Testes que requerem mais de um passo
• Muitos parâmetros ou parâmetros boolean
• Métodos que não são mais utilizados ou
  fazem muita coisa
• Responsabilidade fora do contexto
• Nomes pequenos e inexpressivos
Maus cheiros
•   Duplicação
•   Intenção obscura
•   Despadronização
•   Números mágicos
•   Desencapsulamento
•   Efeitos colaterais
•   Testes insuficientes
•   Ausência de testes
Lei do escoteiro

Deixe o código mais limpo do que
     quando você o encontrou
Conclusão
• As técnicas e práticas devem começar a fazer
  parte do nosso dia a dia
• Clean code não é apenas uma lista de regras,
  temos que praticar e utilizar
• Temos que nos preocupar com a qualidade do
  código que produzimos
• Controlar o Tamanho: Coisas grandes são
  difíceis de manter, deixe menor para facilitar o
  trabalho
Obrigado !


Contatos:
E-mail: rafaelpaztb@gmail.com
Twitter: @rafaelpaztb
DojoTuba/ForkInTuba:
http://groups.google.com/group/dojotuba

Clean Code - Fork In Tuba

  • 1.
  • 2.
  • 3.
    Enquete • Quem sepreocupa com o código que produz? • Onde vocês trabalham, há algo relacionado a manter o código limpo? • Quem realiza testes do seu código? • Quem pratica TDD?
  • 4.
    O que écódigo limpo? • Código bem escrito • Legível • Elegante • Cuidadoso • Sem duplicações • Fácil manutenção
  • 5.
    Tempo de desenvolvimentox Tempo da aplicação
  • 6.
    Porque escreveu umcódigo sujo? • Estava com pressa.. • Meu gerente quer que o código funcione.. • Muita coisa pra terminar e o tempo é curto! Quando a sujeira aumenta, a produtividade da equipe diminui! O tempo economizado no desenvolvimento é utilizado em dobro na manutenção.
  • 7.
    Objetivo de escreverum código limpo? • Produzir um código melhor • Escrever código para humanos lerem • Reduzir a complexibilidade • Manter a manutenibilidade do código ao longo do tempo • Software não é só para o cliente, mas também para o desenvolvedor
  • 8.
    Como saber seum código está sujo?
  • 9.
    Nomes significativos Tanto as variáveis como as classes e métodos devem responder as seguintes perguntas: - Porque isso existe? - O que isso faz? - Como isso é usado? O nome deve revelar exatamente o propósito Se o nome requer um comentário, então não está revelando sua intenção
  • 10.
    • Não façaisso: int d; // Tempo decorrido em dias • Faça: int tempoDecorridoEmDias; int diasDesdeCriacao; int diasDesdeModificacao;
  • 11.
    • Faça distinções: a1? a2 ? int[] d ? d[0] = a1; ? Nomes com apenas uma letra ou número são difíceis de serem entendidos e encontrados
  • 12.
    public List<int[]> getLista{ List<int[]> lista1 = new ArrayList<int[]>(); for (int[] x : lista) if (x[0] == 4) lista1.add(x); return lista1; } public List<int[]> getCelulasSinalizadas{ List<int[]> celulasSinalizadas = new ArrayList<int[]>(); for (int[] celula : tabuleiro) if (celula[VALOR_STATUS] == SINALIZADA) celulasSinalizadas.add(celula); return celulasSinalizadas; }
  • 13.
    Podemos também refatorar publicList<Celula> getCelulasSinalizadas{ List<Celula> celulasSinalizadas = new ArrayList<Celula>(); for (Celula celula : tabuleiro) if (celula.isSinalizada()) celulasSinalizadas.add(celula); return celulasSinalizadas; }
  • 14.
    Comentários Se foi necessáriocomentar, o código não expressa o que faz Desnecessário indicar o autor do método/classe, seu controle de versão faz isso Comentários não vão melhorar o código! Mas... Comentários podem ser um mal necessário.
  • 15.
    Comentários podem sermentirosos e trazer desinformação! Não recebem manutenção, quanto mais velhos, maior a chance de estarem errados Comentários não vão esconder um código ruim. Quando pensar em comentar, é sinal que o código deve ser refatorado
  • 16.
    Comentários // check if the employee is elegible for benefits if ((employee.flags == 100) && (employee.age > 65)) Explique-se no código! if (employee.isElegibleForBenefits())
  • 17.
    Comentários – Nãofaça! //Obtém a idade atual da pessoa public int Pessoa.ObterIdadeAtual(); • -- Códigos antigos comentados InputStreamResponse response = new InputStreamResponse(); response.setBody(formatter.getResultStream(),formatter.getByteCount()); // InputStream resultsStream = formatter.getResultStream(); // StreamReader reader = new StreamReader(resultsStream);
  • 18.
    Comentários – Nãofaça • Não comente para indicar fechamento de bloco: } // fim do else // fim do while • Na forma html • Javadocs não públicos /** The day of the month. */ private int dayOfMonth; /** * Returns the day of the month. * * @return the day of the month. */ public int getDayOfMonth() { return dayOfMonth; }
  • 19.
    Comentários podem serúteis • API pública • Avisos de consequência que um código pode causar • Mostrar a intenção por trás de uma decisão, e não apenas para informação
  • 20.
    Classes / Métodos Devemser pequenos! “A primeirA regrA dos métodos é que eles devem ser pequenos. A segunda regra é que eles devem ser menores AindA.” Uncle Bob Classes menores são mais fáceis de se compreender.
  • 21.
    • Devem fazerapenas UMA coisa, e apenas isso Mas como identificar se o método faz apenas uma coisa?
  • 22.
    Leia o queo método faz e tente extrair um novo método dentro dele. Evite passar parâmetros booleanos, isso implica que o método faz mais de uma coisa
  • 23.
    Quando escrevo ummétodo, ele é feio, grande, cheio de if’s e loops. Há nomes pouco expressivos e duplicação de código. Depois eu refatoro meu método, extraio outros métodos (que fazem apenas uma coisa), troco nomes de variáveis e elimino a duplicação.
  • 24.
    Parâmetros • A quantidadeideal de parâmetros para um método/função é ZERO. • Depois vem UM parâmetro, depois DOIS parâmetros. • Evite um método com TRÊS parâmetros!
  • 25.
    • Tenha umexcelente motivo para métodos com mais de três parâmetros, mas em geral, não devem ser usados • Quanto maior o número de parâmetros, mais difícil de entender o método • Métodos com mais parâmetros são complicados para testar, pois possuem saídas diferentes.
  • 26.
    Evite efeitos colaterais publicboolean checkPassword(String password){ String passwordStatus = crypto.decrypt(password); if (passwordStatus.equals(“OK”)){ Session.initialize(); return true; } return false; }
  • 27.
    CQS – CommandQuery Separation Métodos devem fazer algo ou retornar algo, mas não as duas coisas. Isso gera confusão, além de atribuir mais de uma responsabilidade.
  • 28.
    DRY – Don’tRepeat Yourself Evite duplicidade no seu código, preste atenção e reaproveite seus métodos.
  • 29.
    SRP – Princípioda Responsabilidade Única Esse princípio diz que deve existir um e somente UM MOTIVO para que uma classe mude Esse é um dos conceitos mais importantes em OO, identificar as responsabilidades e criar melhores abstrações.
  • 30.
    Formatação Formatar seu códigoé essencial, a legibilidade do seu código facilita mudanças e o entendimento. Combine com sua equipe qual a indentação que será utilizada, para a leitura ser fácil entre todos os envolvidos. Evite níveis de indentação maior que 2, o código fica mais fácil de compreender
  • 31.
    Espaçamento • De espaçoentre operadores, parâmetros e vírgulas
  • 32.
    Tratamento de erros Tratar erros é responsabilidade do desenvolvedor, temos que garantir que nosso código tem tratamento para os erros que podem ocorrer.
  • 33.
    Use exceptions aoinvés de retornar códigos de erro. Quem chama um método deve verificar se ocorreu um erro, mas isso pode ser esquecido. Forneça o contexto da exception, criando mensagens informativas sobre o que aconteceu, o que estava tentando fazer e por que o erro ocorreu.
  • 34.
    Separe regras denegócio de erros ou outras situações try { MealExpenses expenses = expensesDao.getMeals(); total += expenses.getTotal(); } catch (MealExceptionNotFound e) { total += expenses.getMealPerDiem(); }
  • 35.
    Não retorne NULL,não passe NULL Prefira retornar exceções, objetos especiais ou coleções vazias Tente evitar, pois sempre corremos o risco de receber as famosas NullPointerExceptions
  • 36.
    TESTES Pra testar ocódigo eu perco muito tempo! Verdade !
  • 37.
    Mas não testaro código eu perco muito mais tempo do que se tivesse testado.
  • 38.
    Use TDD Com TDDvocê não vai escrever código enquanto não tiver um teste falhando Não vai escrever teste do que o suficiente para falhar Não vai escrever código a mais, afinal, seu teste está passando, não preciso de mais código.
  • 39.
    UM conceito porteste, não faça vários asserts em um mesmo teste, um assert por teste O teste deve ser rápido e de fácil entendimento, possuir respostas booleanas e sempre retornar o mesmo resultado
  • 40.
    Refatore seu Teste •Tão importante quanto seu código, seu teste deve ser limpo constantemente. • Quanto mais sujo o teste, mais difícil dar manutenção. • Se deixar seus testes apodrecerem, seu código também apodrecerá
  • 41.
    “todA linhA decódigo que você escreve deve estar testada, e ponto finAl! ” Uncle Bob
  • 42.
    Maus Cheiros Sesentir que o código está com um "cheiro" estranho, é um bom indício que deve limpa-lo Mas o que é mau cheiro em código?!
  • 43.
    Maus Cheiros • Comentáriospobres, obsoletos e redundantes • Código comentado • Testes que requerem mais de um passo • Muitos parâmetros ou parâmetros boolean • Métodos que não são mais utilizados ou fazem muita coisa • Responsabilidade fora do contexto • Nomes pequenos e inexpressivos
  • 44.
    Maus cheiros • Duplicação • Intenção obscura • Despadronização • Números mágicos • Desencapsulamento • Efeitos colaterais • Testes insuficientes • Ausência de testes
  • 45.
    Lei do escoteiro Deixeo código mais limpo do que quando você o encontrou
  • 46.
    Conclusão • As técnicase práticas devem começar a fazer parte do nosso dia a dia • Clean code não é apenas uma lista de regras, temos que praticar e utilizar • Temos que nos preocupar com a qualidade do código que produzimos • Controlar o Tamanho: Coisas grandes são difíceis de manter, deixe menor para facilitar o trabalho
  • 47.
    Obrigado ! Contatos: E-mail: rafaelpaztb@gmail.com Twitter:@rafaelpaztb DojoTuba/ForkInTuba: http://groups.google.com/group/dojotuba