Código limpo

948 visualizações

Publicada em

Programação limpa em Java

Publicada em: Tecnologia
  • Seja o primeiro a comentar

Código limpo

  1. 1. Programação limpa em JavaMódulo 01 - Nomenclatura, Funções e Comentários Data: 17/07/2012 Formador: Marcio Romualdo da Silva Email: marcioromualdo@yahoo.com.br1
  2. 2. Objetivos Geral:  No final da sessão o formando será capaz de escrever código Java de forma limpa, clara e de fácil manutenção. Específicos:  No final da sessão o formando será capaz de, na linguagem Java:  Criar variáveis com nomes significativos, sem precisar de comentários.  Criar funções com nomes significativos, sem precisar de comentários.  Escrever funcões pequenas com apenas uma única intenção.  Escrever comentários que ajudam na leitura clara do código.  Identificar os comentários que atrapalham a leitura clara do código. 2
  3. 3.  Código Sujo versus Código Limpo 3
  4. 4. O que é um código limpo? Simples e direto Legível (readable) Elegante e eficiênte Com mínimas dependências para fácil manutenção Com nomes significativos Sem duplicação 4
  5. 5. Por quê você escreveu código sujo? Estava tentando ir mais rápido? Estava com pressa? Seu chefe poderia ficar zangado se você tomasse tempo para limpar o código? Estava cansado de trabalhar no projeto e queria acabar logo? Havia outras coisas havia prometido terminar e o tempo era curto? 5
  6. 6. O custo total da sujeira  Assim que a sujeira aumenta, a produtividade da equipa diminui, aproximando do zero. 6
  7. 7. Nomes Significativos Use nomes que revelem a sua intenção!  Compare: int d; // elapsed time in days  Com: int elapsedTimeInDays; 7
  8. 8. Nomes Significativos Use nomes que revelem a sua intenção!  Qual o propósito deste código? public List getThem() { List list1 = new ArrayList(); for (int[] x : theList) { if (x[0] == 4) { list1.add(x); } } return list1; } 8
  9. 9. Nomes Significativos Nós podems melhorar o código consideravelmente: public List getFlaggedCells() { List flaggedCells = new ArrayList(); for (int[] cell : gameBoard) { if (cell[STATUS_VALUE] == FLAGGED) { flaggedCells.add(cell); } } return flaggedCells; } 9
  10. 10. Nomes Significativos Faça distinções significativas entre as variáveis!  Nomeação usando números em série (a1, a2, .. aN) é o oposto de nomeação intencional. public static void copyChars(char a1[], char a2[]) { for (int i = 0; i < a1.length; i++) { a2[i] = a1[i]; } } 10
  11. 11. Nomes Significativos A função se lê muito melhor quando “source” e “destination” são usados comoargumentos. public static void copyChars(char source[], char destination[]) { for (int i = 0; i < source.length; i++) { destination[i] = source[i]; } } 11
  12. 12. Nomes Significativos Use nomes pronunciáveis! Compare: class DtaRcrd102 { private Date genymdhms; private Date modymdhms; private final String pszqint = "102"; /* ... */ } Com: Conversa inteligente: “Olá, João, class Customer { dê uma olhada nos dados deste private Date generationDate; cliente! A data de geração do private Date modificationDate; está carregada com a data de private final String recordId = "102"; amanhã! Como isto é possível?” /* ... */ } 12
  13. 13. Nomes Significativos Use nomes fáceis de encontrar (Searchable Names)!  Se uma variável deve ser usada em vários lugares no código, dê um nome de fácil procura. Compare: int s = 0; for (int j=0; j<10; j++) { s += (t[j])/5; } Com: int NUMBER_TASKS = 10; int sum = 0; for (int j=0; j < NUMBER_TASKS; j++) { sum += (taskEstimate[j]) / WORK_DAYS_PER_WEEK; } 13
  14. 14. Nomes Significativos Programadores Java não necessitam de notações hungaras (sName, iAge,etc) nem de colocarem qualquer prefixo nas variáveis. Compare: public class Part { private String description; void setDescription(String str_description) { description = str_description; } } Com: public class Part { String description; void setDescription(String description) { this.description = description; } } 14
  15. 15. Funções As funções devem ser pequenas! Transparente óbvias! Sem duplicação! Fazem apenas uma coisa! Têm nomes descritivos e significativos!  Não tenha medo de escolher um nome longo!  Um nome longo e descritivo é melhor que um nome curto e enigmático. 15
  16. 16. Funções – Número ideial de argumentos O número ideial de argumentos em uma função é zero. Depois vem um, seguido por dois. Três argumentos deverão ser evitados quando possível. Mais de quatro argumentos requerem uma justificação especial. Por quê?  Argumentos são difíceis de ponto de vista dos testes. Imaginem a dificuldade em escrever todos os casos de testes para assegurar que as várias combinações dos argumentos trabalham corretamente. 16
  17. 17. Funções - Argumentos booleanos (true / false) Argumentos booleanos são feios. Passando um booelan em uma função é umaprática terrível. Ele imediatamente complica a assinatura do método, proclamando em voz altaque a função faz mais de uma coisa:  Faz um coisa se o argumento for true e outra coisa se o argumento false! Neste caso, nós devemos dividir a função em duas! 17
  18. 18. Funções - Como escrever funções Quando eu escrevo funções, elas saem longas e complicadas. Elas têm um monte de “Ifs“ e “loops”. Os nomes são arbitrários, e existe duplicação de código. Então eu refino o código, dividindo em mais funções (que só fazem uma coisa), trocando os nomes, eliminando a duplicação. 18
  19. 19. Comentários Comentários mentem. Nem sempre, e não intencionalmente, mas com muitafrequência.  A razão é simples. Programadores não podem realisticamente mantê-los! Uma das razões para escrever comentários é ver um código confuso edesorganizado . Então pensamos: vamos escrever um comentário!  Antes de gastar tempo com comentários no código, é melhor limpá-lo, reescrevendo-o! 19
  20. 20. Comentários - Explique-se no código Compare: // Check to see if the employee is eligible for full benefits if ((employee.flags & HOURLY_FLAG) && (employee.age > 65)) { … } Com: if (employee.isEligibleForFullBenefits()) { … }  Leva poucos segundos de pensamento para sabermos a intenção do código. 20
  21. 21. Comentários - Bons comentários Alguns comentários são necessários ou benéficos.-- Comentários Legais (Legal Comments) Algumas vezes a nossa empresa nos força a escrever certos comentários por razões legais. // Copyright (C) 2003,2004,2005 by Infosistema, Inc. All rights reserved. // Released under the terms of the GNU General Public License version 2 or later. 21
  22. 22. Comentários - Bons comentários-- Comentários de explicação da intenção // This is our best attempt to get a race condition // by creating large number of threads. for (int i = 0; i < 25000; i++) { WidgetBuilderThread widgetBuilderThread = new WidgetBuilderThread(widgetBuilder, text, parent, failFlag); Thread thread = new Thread(widgetBuilderThread); thread.start(); } Podem não concordar com a solução do programador, mas ao menos sabem o queele estava tentando fazer. 22
  23. 23. Comentários - Bons comentários-- Comentários de Clarificação Algumas vezes ajudam a traduzir o significado de códigos obscuros. assertTrue(a.compareTo(b) == 0); // a == b assertTrue(a.compareTo(b) != 0); // a != b É um risco substancial, é claro, que os comentários de clarificação estejamincorretos. Então tomem cuidado para que sejam precisos! 23
  24. 24. Comentários - Bons comentários-- Comentários TODO (para fazer)  Algumas vezes é razoável deixar notas em forma de comentários //TODO  São tarefas deviam ter sido feitas, mas por algum motivo não pode ser feita no momento.  Pode ser um lembrete para apagar um recurso substituído (deprecated)  Pode ser um lembrete para alguém olhar para o problema  (Neste caso, pode-se também usar //FIXME)  Pode ser um lembrete para fazer um mudança que está pendente de um evento planeado.-- Comentários Javadocs em bibliotecas públicas (Public APIs)  Não existe nada mais útil e satisfatório que um bons comentários javadocs em bibliotecas públicas! 24
  25. 25. Comentários - Maus comentários-- Comentários de ruído (Noise Comments) Apenas reafirmam o óbvio e não fornecem novas informações. /** 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; } 25
  26. 26. Comentários - Maus comentários-- Comentários com atribuições Bylines /* Created by Marcio Silva */ String name = “test“; /* Added by Marcio Silva */ If (!customer.equals(“”)) { Hoje em dia, temos ótimos controladores de versões (CVS, SVN, GIT, etc)que irão nos lembrar quem alterou o código! 26
  27. 27. Comentários - Maus comentários-- Códigos antigos comentados (Commented-Out Code) InputStreamResponse response = new InputStreamResponse(); response.setBody(formatter.getResultStream(), formatter.getByteCount()); // InputStream resultsStream = formatter.getResultStream(); // StreamReader reader = new StreamReader(resultsStream); Outras pessoas que vêm o código comentário não têm coragem de apagá-lo. Elas pensam que eles estão lá por algum motivo.  São importantes?  Deixaram paralembrar uma mudança iminente ?  Ou alguém comentou anos atrás e simplesmente não limpou ? Hoje em dia, temos ótimos controladores de versões (CVS, SVN, GIT, etc) que irão noslembrar as alterações no código! 27
  28. 28. Comentários - Maus comentários-- Comentários com muita informação (Too Much Information) Não coloquem discussões históricas ou irrelevante s em seus comentários. Alguém lendo o código não tem necessidade ler toda esta informação./* RFC 2045 - Multipurpose Internet Mail Extensions (MIME) Part One: Format of Internet Message Bodies section 6.8. Base64 Content-Transfer-Encoding The encoding process represents 24-bit groups of input bits as output strings of 4 encoded characters. Proceeding from left to right, a 24-bit input group is formed by concatenating 3 8-bit input groups. These 24 bits are then treated as 4 concatenated 6-bit groups, each of which is translated into a single digit in the base64 alphabet. When encoding a bit stream via the base64 encoding, the bit stream must be presumed to be ordered with the most-significant-bit first. That is, the first bit in the stream will be the high-order bit in the first 8-bit byte, and the eighth bit will be the low-order bit in the first 8-bit byte, and so on. 28*/
  29. 29. Síntese Para termos um código limpo em Java, devemos: Criar variáveis com nomes significativos  Criar funções com nomes significativos  Escrever funções pequenas com apenas uma intenção  Escrever apenas bons comentários que ajudam na leitura clara do código 29
  30. 30. Próxima Sessão? Módulo 02  Formatar o código fonte de maneira organizada e estruturada  Identificar as diferenças entre objetos e estrutura de dados  Criar classes limpas e de fácil leitura 30
  31. 31. Cuide bem do seu código! Mantenha-o limpo!31
  32. 32. Muito Obrigado!  Formador: Marcio Romualdo da Silva Email: marcioromualdo@yahoo.com.br32

×