32
Programação limpa em Java Módulo 01 - Nomenclatura, Funções e Comentários 1 Data: 17/07/2012 Formador: Marcio Romualdo da Silva Email: [email protected]

Código limpo

Embed Size (px)

DESCRIPTION

Programação limpa em Java

Citation preview

Page 1: Código limpo

Programação limpa em JavaMódulo 01 - Nomenclatura, Funções e Comentários

1

Data: 17/07/2012Formador: Marcio Romualdo da Silva

Email: [email protected]

Marcio
Page 2: Código limpo

Objetivos

2

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.

Page 3: Código limpo

3

Código Sujo versus Código Limpo

Page 4: Código limpo

O que é um código limpo?

4

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

Page 5: Código limpo

Por quê você escreveu código sujo?

5

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?

Page 6: Código limpo

O custo total da sujeira

Assim que a sujeira aumenta, a produtividade da equipa diminui, aproximando do zero.

6

Page 7: Código limpo

Nomes Significativos

7

Use nomes que revelem a sua intenção!

Compare:

int d; // elapsed time in days

Com:

int elapsedTimeInDays;

Page 8: Código limpo

Nomes Significativos

8

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;}

Page 9: Código limpo

Nomes Significativos

9

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;}

Page 10: Código limpo

Nomes Significativos

10

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]; }}

Page 11: Código limpo

Nomes Significativos

11

A função se lê muito melhor quando “source” e “destination” são usados como argumentos.

public static void copyChars(char source[], char destination[]) { for (int i = 0; i < source.length; i++) { destination[i] = source[i]; }}

Page 12: Código limpo

Nomes Significativos

12

Use nomes pronunciáveis!

Compare:class DtaRcrd102 { private Date genymdhms; private Date modymdhms; private final String pszqint = "102"; /* ... */}

Com:class Customer { private Date generationDate; private Date modificationDate; private final String recordId = "102"; /* ... */}

Conversa inteligente: “Olá, João, dê uma olhada nos dados deste cliente! A data de geração do está carregada com a data de amanhã! Como isto é possível?”

Page 13: Código limpo

Nomes Significativos

13

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;}

Page 14: Código limpo

Nomes Significativos

14

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; }}

Page 15: Código limpo

Funções

15

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.

Page 16: Código limpo

Funções – Número ideial de argumentos

16

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.

Page 17: Código limpo

Funções - Argumentos booleanos (true / false)

17

Argumentos booleanos são feios. Passando um booelan em uma função é uma prática terrível.

Ele imediatamente complica a assinatura do método, proclamando em voz alta que 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!

Page 18: Código limpo

Funções - Como escrever funções

18

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.

Page 19: Código limpo

Comentários

19

Comentários mentem. Nem sempre, e não intencionalmente, mas com muita frequê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 e desorganizado . Então pensamos: vamos escrever um comentário!

Antes de gastar tempo com comentários no código, é melhor limpá-lo, reescrevendo-o!

Page 20: Código limpo

Comentários - Explique-se no código

20

Compare:// Check to see if the employee is eligible for full benefitsif ((employee.flags & HOURLY_FLAG) && (employee.age > 65)) { … }

Com:if (employee.isEligibleForFullBenefits()) {

…}

Leva poucos segundos de pensamento para sabermos a intenção do código.

Page 21: Código limpo

Comentários - Bons comentários

21

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.

Page 22: Código limpo

Comentários - Bons comentários

22

-- 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 que ele estava tentando fazer.

Page 23: Código limpo

Comentários - Bons comentários

23

-- Comentários de Clarificação

Algumas vezes ajudam a traduzir o significado de códigos obscuros.

assertTrue(a.compareTo(b) == 0); // a == bassertTrue(a.compareTo(b) != 0); // a != b

É um risco substancial, é claro, que os comentários de clarificação estejam incorretos. Então tomem cuidado para que sejam precisos!

Page 24: Código limpo

Comentários - Bons comentários

24

-- 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!

Page 25: Código limpo

Comentários - Maus comentários

25

-- 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;}

Page 26: Código limpo

Comentários - Maus comentários

26

-- 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!

Page 27: Código limpo

Comentários - Maus comentários

27

-- 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 para lembrar 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 nos lembrar as alterações no código!

Page 28: Código limpo

Comentários - Maus comentários

28

-- 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.

*/

Page 29: Código limpo

Síntese

29

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

Page 30: Código limpo

Próxima Sessão?

30

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

Page 31: Código limpo

Cuide bem do seu código!

31

Mantenha-o limpo!

Page 32: Código limpo

Muito Obrigado!

32

Formador: Marcio Romualdo da SilvaEmail: [email protected]

Marcio