refatoração e boas práticas no desenvolvimento de software com a linguagem java - márcio josué...

25
Refatoração e Boas Práticas no Desenvolvimento de Software com Java Márcio Torres

Upload: tchelinux-slides

Post on 11-Jun-2015

2.915 views

Category:

Technology


1 download

DESCRIPTION

Escrever um bom código, legível, eficiente e seguro, é uma competência necessária para codificar em qualquer linguagem. O objetivo é abordar técnicas de refatoração, boas práticas, código seguro e testes, utilizando exemplos com a linguagem Java. A bibliografia indicada é Refatoração, do Martin Fowler, e Effective Java do Joshua Bloch.

TRANSCRIPT

Page 1: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Refatoração e Boas Práticas no Desenvolvimento de Software com Java

Márcio Torres

Page 2: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Agenda

● Apresentação● Introdução● Mãos a obra!● Bibliografia

Page 3: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Apresentação“Quem é Márcio Torres?”

● Primeiro contato com um computador na década de 90, um CP 500 com Basic embedded;

● Desenvolvedor dBase e Clipper;● Instrutor de Informática na Degraus;● Suporte e Manutenção;● Instrutor de Informática no Senac;● Desenvolvedor Java;● Professor no IFRS nos cursos técnico e tecnólogo;

Page 4: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

IntroduçãoO que veremos e por que é importante?

● Conversaremos sobre:● Boas práticas lidando com: Strings, 

Números, Coleções;● Como lidar com: Nulos, Exceções, 

Passagem de parâmetros;● Problemas típicos de domínio, assinaturas 

de métodos;● Como melhorar o código aplicando 

refatorações;

● É importante por que:● Torna a aplicação mais resistente a falhas;● Deixa o código mais fácil de ler;● A aplicação fica mais robusta e rápida;● O mercado busca bons profissionais;

● Práticas transversais:

● Fazendo um bom design;● Aderir a convenções;● Seguir princípios de design 

orientado a objetos;

Page 5: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Performance

Robustez

Manutenibilidade

Testabilidade

Responsividade

ConfiabilidadeLegibilidade

É sobre requisitos não funcionais ...

… e qualidade interna.

Extensibilidade

Page 6: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

● Exemplos práticos, com embasamento técnico e/ou bibliográfico;

Mãos a obra

Page 7: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Lidando com Strings ...Como instanciar Strings

Entenda como a memória é gerenciada na plataforma Java

String q = "sim";

if ("sim".equals(q)) {

System.out.println("SIM!!!");

} else {

System.out.println("NÃO??!! COMO NÃO?!!");

}

String q = new String("sim");

if (q == "sim") {

System.out.println("SIM!!!");

} else {

System.out.println("NÃO??!! COMO NÃO?!!");

}

As instâncias de Strings literais são armazenadas em um espaço de memória chamado Permanent Generation. Elas são reusadas, com a exceção de quando é usado o operador new, que por consequência cria dois objetos.

O operador == compara igualdade da variável, não dos objetos. Sempre use equals, e prefira passar a variável como parâmetro do equals.

Page 8: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Organização da memória na Máquina Virtual Java da Sun Oracle

Page 9: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Lidando com Strings ...Como concatenar Strings

Conheça a API do Java, estude­a.

String nomes = “Nomes: “;

for (int i = 1; i < 1000000; i++) {

nomes = nomes + “, “ + getNome();

}

StringBuilder nomes = new StringBuilder(“Nomes: “);

for (int i = 1; i < 1000000; i++) {

nomes.append(“, “).append(getNome());

}

Use StringBuilder para concatenar muitas Strings, é mais rápido e usa menos memória

Cada resultado com o operador + gera uma nova String

Page 10: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Lidando com Números ...Como declarar membros numéricos

Prefira tipos primitivos sempre que possível, mas cuidado com o Primitive Obsession Antipattern!

Tipos primitivos consomem menos memória, além de ter um footprint menor

class PlanoDesconto {

Double rendaMinima;Double rendaMaxima;Integer idadeMinima;Integer idadeMaxima; class PlanoDesconto {

double rendaMinima;double rendaMaxima;int idadeMinima;int idadeMaxima;

Tipos primitivos reduzem a necessidade de boilerplate code

public double getValorMensalComDesconto() {

return valorMensal - valorDesconto;

}

public Double getValorMensalComDesconto() {double _valorMensal = valorMensal == null ? 0 : valorMensal;double _valorDesconto = valorDesconto == null ? 0 : valorDesconto;return _valorMensal - _valorDesconto;

}

Page 11: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Evitando NullPointerException's  ...Escrevendo métodos seguros

Evite NPE escrevendo métodos testados e seguros, pensando:“E se o parâmetro vier nulo? E se o valor recebido não é tratado?”

public List<Foto> getFotos1(String ordem, final Integer direcao) {if (ordem.equals("descricao")) {

Collections.sort(fotos, new Comparator<Foto>() {@Overridepublic int compare(Foto o1, Foto o2) {

if (direcao == 1) {return o1.getDescricao().compareTo(o2.getDescricao());

} else if (direcao == 2) {return o2.getDescricao().compareTo(o1.getDescricao());

}return 0;

public List<Foto> getFotos2(String ordem, final Integer direcao) {if ("descricao".equals(ordem)) {

Collections.sort(fotos, new Comparator<Foto>() {@Overridepublic int compare(Foto o1, Foto o2) {

if (new Integer(1).equals(direcao)) {return o1.getDescricao().compareTo(o2.getDescricao());

} else if (new Integer(2).equals(direcao)) {return o2.getDescricao().compareTo(o1.getDescricao());

}return 0;

Page 12: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Não use Strings onde outro tipo é mais adequadoAvalie definir um comportamento default para o caso de omissão …Desenhe para que nulos não sejam passados como parâmetros ...

Escrevendo métodos seguros e intuitivos ...

public List<Foto> getFotos(Ordem ordem, final Direcao direcao) {

if (Ordem.DESCRICAO.equals(ordem)) {Collections.sort(fotos, new Comparator<Foto>() {

@Overridepublic int compare(Foto o1, Foto o2) {

if (Direcao.DESCENDENTE.equals(direcao)) {return o2.getDescricao().compareTo(o1.getDescricao());

}

return o1.getDescricao().compareTo(o2.getDescricao());

public List<Foto> getFotos(Ordem ordem) {

return getFotos(ordem, null);

}Sobrecarregue métodos ao invés de passar nulos para parâmetros opcionais

Page 13: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Escrevendo métodos legíveis ...class BadReportPreview {

public void show(String dados,boolean impressora) {

if (impressora) {// mostra na impressora

} else {// mostra no monitor

}}

}

class GoodReportPreview {

public enum Destino {TELA, IMPRESSORA;

}

public void show(String dados, Destino destino) {if (Destino.TELA.equals(destino)) {

// mostra na tela} else if (Destino.IMPRESSORA.equals(destino)) {

// mostra na impressora} else {

throw new IllegalArgumentException("Destino nao foi informado");

}}

}

Não parece melhor chamar o preview na impressora assim:preview.show(dados, Destino.IMPRESSORA);

Do que assim:

preview.show(dados, true);

Avalie usar enumerados para passar no método ao invés de boleanos ...

Page 14: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Convenções para métodos ...Entendendo algumas convenções

Métodos tem retorno quando retornam uma nova instância ...Se o método altera a instância parametrizada use void …Cuidado com os métodos que trazem efeitos colaterais, isto é, alteram a instância parametrizada  ...

public List<Livro> ordernarPorTitulo(List<Livro> livros) {List<Livro> copia = new ArrayList<Livro>(livros);Collections.sort(copia, new Comparator<Livro>() {

@Overridepublic int compare(Livro o1, Livro o2) {

return o1.getTitulo().compareTo(o2.getTitulo());}

});return copia;

}

public void ordernarPorTitulo(List<Livro> livros) {Collections.sort(livros, new Comparator<Livro>() {

@Overridepublic int compare(Livro o1, Livro o2) {

return o1.getTitulo().compareTo(o2.getTitulo());}

});}

Page 15: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Lidando com coleções ...Implementado os métodos necessários ...

Sempre sobrescreva equals e hashCode nas classes em que suas instâncias participarão de coleções, especialmente baseadas em Hash.Siga o contrato. Lembre: objetos considerados iguais devem ter o mesmo hashCode.

class Foto {...

@Overridepublic int hashCode() {

final int prime = 31;int result = 1;result = prime * result + id;return result;

}

@Overridepublic boolean equals(Object obj) {

if (this == obj) return true;if (obj == null) return false;if (getClass() != obj.getClass()) return false;Foto other = (Foto) obj; if (id != other.id) return false;return true;

}

Page 16: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Lidando com coleções ...Devolva listas vazias invés de nulo. Isto fará com que o cliente de sua API não tenha que escrever qualquer boilerplate code;

for (Livro livro : livros) {

if (livro.getKeywords() != null && livro.getKeywords().contains(k)) {count++;

}

}

for (Livro livro : livros) {

if (livro.getKeywords().contains(k)) {count++;

}

}

É possível instanciar coleções na criação da classe, que tem uma performance pior. Se quiser melhorar a performance pode fazer Lazy Initialization ou atuar como delegado da coleção (melhor aproximação);

Page 17: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Lidando com exceções ...Fazer um design com ou sem exceções ?

Lance exceções só quando necessário, exceções diminuem a performance ...Se for o caso, propague o stacktrace e documente bem …Não ignore as exceções na hora de tratá­las...Use Checked Exceptions para recuperáveis e Runtime Exceptions para falhas do sistema ...

public Conta load(Integer id) throws RegistroNaoEncontradoException {if (id == null) throw new RegistroNaoEncontradoException("ID nulo");Conta c = contas.get(id);if (c == null) throw new RegistroNaoEncontradoException();return c;

}

public Conta find(Integer id) {if (id == null) return null;return contas.get(id);

}

public Conta find(Integer id) {if (id == null) {

throw new IllegalArgumentException("Id inválido",new NullPointerException("ID nulo"));

}return contas.get(id);

}

Page 18: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Lidando com Three Valued Logic ...A maldição herdada pelos SGBD's

Reduza a necessidade de Boiler Plate Code …Use primitivos, ou trate na classe …Pense qual é o valor por omissão ...

for (Conta c : contas) {if (c.isEspecial() != null && c.isEspecial()) {

contasEspeciais++;}

}

for (Conta c : contas) {if (c.isEspecial()) {

contasEspeciais++;}

}

Page 19: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Refatorações ...

Alguns maus cheiros:Cadeias de mensagens ...Campo temporário ...Classes, métodos grandes ...Método Longo ...Lista longa de parâmetros ...

Detectar mau cheiro no código …Melhorar a qualidade do código …Não alterar o comportamento ...

Alguns técnicas de refatoração:Extrair método;Extrair classe;.Renomear método;Renomear atributo;Objeto parâmetro;Usar fábrica ao invés de construtor;Usar constante ao invés de número mágico;

Page 20: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Renomeando métodos e atributos ...Use nomes expressivos ...

Não use magic numbers, prefira enumerados ...

for (Conta c : c1) {if ( ! c2.contains(c1)) {

webService.envComAval(c1);}

}

for (Conta contaNaBase : contasNaBaseDados) {if ( ! contasNoERP.contains(contaNaBase)) {

webService.enviaContaParaComissaoAvaliadora(contaNaBase);}

}

Sempre que for adicionar um comentário, pergunte­se:“Como posso melhorar o código ao ponto deste comentário não ser mais necessário?”

Conta c = new Conta();c.numero = 66410;c.tipo = 1;

Conta c = new Conta();c.numero = 66410;c.tipo = Conta.FISICA;

Conta c = new Conta();c.numero = 66410;c.tipo = TipoConta.FISICA;

Page 21: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Extrair método ...Evite métodos muito longos ...

Divida funcionalidades usando métodos privados, de preferência reusáveis ...

public static void processaContas() {ContaRepository contaRepository = new ContaRepository();List<Conta> c1 = contaRepository.findContas();

Collections.sort(c1, new Comparator<Conta>() {@Overridepublic int compare(Conta o1, Conta o2) {

if (o1.numero > o2.numero) return 1;if (o2.numero < o1.numero) return -1;return 0;

}});

// ...

public static void processaContas() {ContaRepository contaRepository = new ContaRepository();List<Conta> contas = contaRepository.findContas();

ordena(contas);

// ...

Page 22: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Mais refatorações ...

● Usar fábrica ao invés de construtor ...● Trocar número mágico por constante ...● Introduzir variável explicativa ...● Usar objeto parâmetro …● E várias outras ...

Page 23: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Na primeira vez, apenas implemente, lide com as duplicações mais evidentes, mas na terceira vez que fizer algo semelhante, refatore! 

Martin Fowler

Page 24: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

Bibliografia Recomendada● Estes livros estão entre os melhores na bibliografia para quem já 

programa com Java (e outras linguagens) e deseja tornar­se um desenvolvedor melhor.

Page 25: Refatoração e Boas Práticas no Desenvolvimento de Software com a Linguagem Java - Márcio Josué Ramos Torres

http://www.refactoring.com/catalog/http://c2.com/xp/CodeSmell.htmlhttp://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOodhttp://marciojrtorres.blogspot.com/

[email protected]