Your SlideShare is downloading. ×

Evento CODERS

205

Published on

Apresentação para o evento conjunto M4U, Bemobi e Mobicare onde foram apresentados as principais boas práticas para programação usando a linguagem Java.

Apresentação para o evento conjunto M4U, Bemobi e Mobicare onde foram apresentados as principais boas práticas para programação usando a linguagem Java.

Published in: Technology
2 Comments
1 Like
Statistics
Notes
No Downloads
Views
Total Views
205
On Slideshare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
2
Comments
2
Likes
1
Embeds 0
No embeds

Report content
Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
No notes for slide

Transcript

  • 1. Java Best Practices
  • 2. Classes e Interfaces
  • 3. Classes e Interfaces Visibilidade { } Faça com que cada classe ou variável tenha o acesso mais restrito possível { } Variáveis de instância nunca devem ser públicas public StatusCliente status = StatusCliente.ATIVO; protected StatusCliente status = StatusCliente.ATIVO;
  • 4. Classes e Interfaces Desacoplamento { } Evite ao máximo o acoplamento entre classes ou componentes conta1.getExtratoFisico(); GeradorExtrato.geraExtratoFisico(conta1);
  • 5. Classes e Interfaces Singletons { } Declare a variável de instância final e o construtor private { } Singletons para aplicações multithread public static Banco getInstance() { if (banco == null) { banco = new Banco(); } return banco; }
  • 6. Classes e Interfaces Singletons { } Declare a variável de instância final e o construtor private { } Singletons para aplicações multithread public static Banco getInstance() { if (banco == null) { synchronized (Banco.class) { if (banco == null) { banco = new Banco(); } } } return banco; }
  • 7. Classes e Interfaces Criação de Objetos { } Evite criar objetos desnecessários public String geraExtratoOnline() { Integer ag = this.getAgencia(); Long cc = this.getNumeroConta(); List<Movimentacao> e = this.getExtrato(); // ... StringBuilder extrato = new StringBuilder(); extrato.append(montaCabecalho(ag, cc)); for(Movimentacao m : e){ extrato.append(m.getDataMovimentacao()).append(";"); extrato.append(m.getTipoMovimentacao()); extrato.append(";").append(m.getValor()).append("n"); } // ... return extrato.toString(); }
  • 8. Classes e Interfaces Criação de Objetos { } Evite criar objetos desnecessários public String geraExtratoOnline() { // ... StringBuilder extrato = new StringBuilder(); extrato.append(montaCabecalho(this.getAgencia(), this.getNumeroConta())); for(Movimentacao m : this.getExtrato()){ extrato.append(m.getDataMovimentacao()).append(";"); extrato.append(m.getTipoMovimentacao()); extrato.append(";").append(m.getValor()).append("n"); } // ... return extrato.toString(); }
  • 9. Classes e Interfaces Estáticos x Não Estáticos { } Prefira elementos estáticos a não estáticos conta1.getExtratoFisico(); GeradorExtrato.geraExtratoFisico(conta1);
  • 10. Classes e Interfaces Encapsulamento { } Proteja as variáveis de sua classe através de getters e setters public StatusCliente status = StatusCliente.ATIVO; protected StatusCliente status = StatusCliente.ATIVO;
  • 11. Classes e Interfaces Composição x Herança { } Prefira composição a herança
  • 12. Classes e Interfaces Composição x Herança { } Prefira composição a herança
  • 13. Classes e Interfaces Interfaces { } Use interface apenas para definição de tipos public abstract class Cliente implements Bloqueavel, StatusCliente { public int status = ATIVO; // ... }
  • 14. Classes e Interfaces Interfaces { } Use interface apenas para definição de tipos public enum StatusCliente { ATIVO, BLOQUEADO } public abstract class Cliente implements Bloqueavel { protected StatusCliente status = StatusCliente.ATIVO; // ... }
  • 15. Classes e Interfaces Classes Final { } Avalie cuidadosamente o design de sua aplicação para definir quando uma classe deve ser declarada como final ou não public final class Banco { /** … */ } public final class Banco { /** … */ }
  • 16. Métodos
  • 17. Métodos Validação < > Validação dos parâmetro da classe public final void transfere(...) throws ... { // Validação dos parâmetros. ValidaParametrosDeTransferencia( ... ); }
  • 18. Métodos Assinatura < > Escolha corretamente as assinaturas de métodos public abstract class Cliente implements Bloqueavel { // ... public abstract String getCliente(); // ... }
  • 19. Métodos Assinatura < > Escolha corretamente as assinaturas de métodos public abstract class Cliente implements Bloqueavel { // ... public abstract String getNome(); // ... }
  • 20. Métodos Varargs < > Utilize varargs com cautela private static String montaRodape(String... param) { BigDecimal saldo = new BigDecimal(param[0]); StringBuilder rodape = new StringBuilder(); rodape.append("Seu saldo atual é ").append(saldo.toPlainString()) .append("n"); int i =0; for (String aviso : param) { if (i != 0){ rodape.append(aviso).append("n"); } i++; } return rodape.toString(); }
  • 21. Métodos Varargs < > Utilize varargs com cautela private String montaRodape(BigDecimal saldo, String... avisos) { StringBuilder rodape = new StringBuilder(); rodape.append("Seu saldo atual é ").append(saldo.toPlainString()) .append("n"); for (String aviso : avisos) { rodape.append(aviso).append("n"); } return rodape.toString(); }
  • 22. Métodos Javadoc < > Lembre-se de documentar sempre seus métodos, especialmente os métodos expostos em API’s private void final final final validaParametrosDePagamento( Conta contaOrigem, BigDecimal valorBoleto, String codigoDeBarras ) throws IllegalArgumentException { ... }
  • 23. Métodos Javadoc < > Lembre-se de documentar sempre seus métodos, especialmente os métodos expostos em API’s /** * Validador dos parâmetros de entrada da função efetuaPagamento(..). * Valida se a conta não é nulas, se o valor valorDoBoleto é positivo * e não nulo e se o codigoDeBarras não é nulo. * @param contaOrigem * @param valorBoleto * @param codigoDeBarras */ private void validaParametrosDePagamento( final Conta contaOrigem, final BigDecimal valorBoleto, final String codigoDeBarras ) throws IllegalArgumentException { ... }
  • 24. Exceptions e Logging
  • 25. Exceptions e Logging Tratamento e Catches Genéricos [ ] Nunca 'suma' com a exception public String geraExtratoFisico() { // ... Writer writer = null; try { // ... writer.close(); } catch (Exception e) { } // ... }
  • 26. Exceptions e Logging Tratamento e Catches Genéricos [ ] Nunca 'suma' com a exception } catch (FileNotFoundException e) { log.severe(String.format("Ocorreu um erro ao gerar o arquivo: %s", e)); } catch (UnsupportedEncodingException e) { log.severe(String.format("Encoding incorreto na hora de gerar um arquivo: %s", e)); } catch (IOException e) { log.severe(String.format("Erro fatal de I/O, contate o administrador do sistema: %s“ , e)); } finally { try {writer.close();} catch (Exception ex) { log.warning(String.format("Erro ao finalizar a escrita do arquivo de extrato: %s" , ex)); } }
  • 27. Exceptions e Logging Declarações Específicas [ ] Declare exceptions específicas que o seu método pode lançar public abstract void sacar(BigDecimal valorSaque) throws Exception; public abstract void sacar(BigDecimal valorSaque) throws ContaBloqueadaException, SaldoInsuficienteException;
  • 28. Exceptions e Logging Exception Original e Throw | Log [ ] Carregue sempre a exception original ao lançar uma nova [ ] Logue a exception apenas uma vez try { banco.transfere(conta1, conta2, new BigDecimal(50l), "Divida Antiga"); } catch (Exception e) { log.info("Erro ao transferir " + e.getMessage()); throw new Exception(e.getMessage()); }
  • 29. Exceptions e Logging Exception Original e Throw | Log [ ] Carregue sempre a exception original ao lançar uma nova [ ] Logue a exception apenas uma vez try { banco.transfere(conta1, conta2, new BigDecimal(50l), "Divida Antiga"); } catch (Exception e) { log.info("Erro ao transferir " + e.getMessage()); }
  • 30. Exceptions e Logging Bloco Finally e Relevância [ ] Nunca lance uma exception de dentro do bloco finally [ ] Só capture exceptions que você realmente for tratar [ ] Lance apenas exceptions relevantes [ ] Lembre-se de colocar informações relevantes na sua exception finally { try { writer.close(); } catch (IOException ex) { throw new Exception(e.getMessage()); } }
  • 31. Exceptions e Logging Bloco Finally e Relevância [ ] Nunca lance uma exception de dentro do bloco finally [ ] Só capture exceptions que você realmente for tratar [ ] Lance apenas exceptions relevantes [ ] Lembre-se de colocar informações relevantes na sua exception finally { try {writer.close();} catch (IOException ex) { log.warning(String.format("Erro ao finalizar (...) de extrato: %s", ex)); } }
  • 32. Exceptions e Logging Throw early catch late [ ] Lance a exception o quanto antes [ ] Aguarde para ter informações suficientes para trata-lá public final void efetuaPagamento(...) throws Exception { validaParametrosDePagamento(contaOrigem, valorBoleto, codigoDeBarras); try { contaOrigem.sacar(valorBoleto); } catch (Exception e) { e.printStackTrace(); } // ... }
  • 33. Exceptions e Logging Throw early catch late [ ] Lance a exception o quanto antes [ ] Aguarde para ter informações suficientes para trata-lá public final void efetuaPagamento(...) throws ContaBloqueadaException, IllegalArgumentException { validaParametrosDePagamento(contaOrigem, valorBoleto, codigoDeBarras); contaOrigem.sacar(valorBoleto); // ... }
  • 34. Exceptions e Logging Controle de Fluxo [ ] NUNCA utilize exceptions para controlar seu fluxo de execução try{ if (param.length <= 0){ throw new Exception("Avisos e Saldo invalidos"); } // ... return rodape.toString(); } catch(Exception e){ return ""; }
  • 35. Exceptions e Logging Reutilização [ ] Tente ao máximo utilizar exceptions já existentes [ ] Não crie exceptions novas se não houver informações realmente utéis private void validaParametrosDePagamento( ... ) throws ErroDeValidacaoException; private void validaParametrosDePagamento( ... ) throws IllegalArgumentException;
  • 36. Exceptions e Logging Encapsulamento [ ] Sempre que possível encapsule suas checked exceptions em unchecked exceptions [ ] Uma regra razoável é que se o cliente pode se recuperar de uma exceção então ela deveria ser checked, caso contrário unchecked. Uma exceção a essa regra são as exceções IllegalArgumentException, NullpointerException e IllegalStateException
  • 37. Exceptions e Logging Performance [ ] Lembre-se que exceptions podem impactar (muito) a performance do software [ ] * Um teste de 10000000 de iterações com com controle de fluxo usando => boolean ~ 62ms => Exception ~ 20891ms * http://stackoverflow.com/questions/567579/how-expensive-are-exceptions
  • 38. Exceptions e Logging Log Level [ ] Trace: Imagine que é proibido usar o “debug” da ide, neste trace deve-se colocar todo o contexto necessário para o entendimento do “contexto”, estado atual das variáveis. [ ] Debug: informações para se ter uma visão do fluxo e das variáveis [ ] Info: Eventos esporádicos inicialização e finalização de componentes, “setup” [ ] Warn: Indica uma situação onde existe um erro temporário, degradação, um possível problema e deve-se observar [ ] Error: Não deveriam ocorrer, indicam a execução de um fluxo alternativo [ ] Fatal: Erros fatais onde há ‘morte’ e não há como o sistema se recuperar
  • 39. Exceptions e Logging Log Level log.finest("Gerando extrato online para a conta: " + conta.toString()); log.info("O extrato foi gerado com sucesso"); log.warning(String.format("Erro ao gravar no arquivo de extrato: %s", ex)); log.severe(String.format("Erro fatal de I/O, contate o admin do sistema: %s", e));
  • 40. Exceptions e Logging Javadoc [ ] Documente suas exceptions /** * Efetua um pagamento com base no número do código de barras. * @param contaOrigem * @param valorBoleto * @param codigoDeBarras * @throws SaldoInsuficienteException Quando não há saldo * @throws ContaBloqueadaException Caso o cliente esteja bloqueado * @throws IllegalArgumentException caso a validação falhe para algum dos parametros */ public final void efetuaPagamento( ... ) throws SaldoInsuficienteException, ContaBloqueadaException, IllegalArgumentException
  • 41. Uso do Null
  • 42. Uso do Null Pontos comuns para NPE { } Chamada de métodos de objetos não inicializados { } Parâmetros passados como null Conta conta1 = null; Conta conta2 = null; try { conta1 = // ... código de inicialização conta2 = // ... código de inicialização } catch (Exception e) { e.printStackTrace(); } log.info("realizando tranferencia da conta" + conta1.getNumeroConta() + " para " + conta2.getNumeroConta());
  • 43. Uso do Null Pontos comuns para NPE { } Chamada de métodos de objetos não inicializados { } Parâmetros passados como null final Conta conta1 = new ContaPoupanca(999l, 1, cliente2); final Conta conta2 = new ContaCorrente(171l, 24, cliente1); try { conta1.depositar(new BigDecimal("10000")); } catch (ContaBloqueadaException e) { log.warning("Não foi possivel incluir fundos nesta conta, ela encontra-se bloqueada"); }
  • 44. Uso do Null Pontos comuns para NPE { } Evite retornar null em metodos cujo retorno definido sejam coleções ou arrays public List<Movimentacao> getExtrato() { if (movimentacoes == null) return null; Collections.sort(movimentacoes); return movimentacoes; }
  • 45. Uso do Null Pontos comuns para NPE { } Evite retornar null em metodos cujo retorno definido sejam coleções ou arrays public List<Movimentacao> getExtrato() { Collections.sort(movimentacoes); return movimentacoes; }
  • 46. Strings
  • 47. Strings Criação de Strings < > inicialização lenta String msg = new String("O extrato foi gerado com sucesso“); Log.info(msg); < > inicialização rápida String msg = "O extrato foi gerado com sucesso“; Log.info(msg);
  • 48. Strings Alteração de Strings < > Lembre-se: objetos do tipo String são imutáveis! public String toString() { String ag = String.valueOf(agencia); String cc = String.valueOf(numeroConta); cc.replaceAll("-",""); return "Conta{" + "agencia=" + ag + ", numeroConta=" + cc + '}'; }
  • 49. Strings Alteração de Strings < > Lembre-se: objetos do tipo String são imutáveis! public String toString() { String ag = String.valueOf(agencia); String cc = String.valueOf(numeroConta); cc = cc.replaceAll("-",""); return "Conta{" + "agencia=" + ag + ", numeroConta=" + cc + '}'; }
  • 50. Strings Alteração de Strings < > Use o operador ‘+’ se todos os operandos forem constantes String s = s1 + s2 É transformado em: String s = new StringBuilder(s1).append(s2).toString();
  • 51. Strings Alteração de Strings < > Use StringBuilder dentro de um loop para atualização < > Use StringBuilder ao invés de reatribuir valores a mesma variável private static String montaRodape(String... param) { // ... String rodape = ""; rodape = rodape + "Seu saldo atual é " + saldo.toPlainString() + "n"; // ... for (String aviso : param) { if (i != 0){ String msg = aviso + "n"; rodape = rodape + msg; } i++; }
  • 52. Strings Alteração de Strings < > Use StringBuilder dentro de um loop para atualização < > Use StringBuilder ao invés de reatribuir valores a mesma variável private static String montaRodape(BigDecimal saldo, String... avisos) { StringBuilder rodape = new StringBuilder(); rodape.append("Seu saldo atual é ").append(saldo.toPlainString()).append("n"); for (String aviso : avisos) { rodape.append(aviso).append("n"); } return rodape.toString(); }
  • 53. Collections
  • 54. Collections Prefira coleções a classes antigas [ ] Dê preferência as coleções do que ao Vector e HashTables
  • 55. Collections Ordenação [ ] Comparator e CompareTo @Override public int compareTo(Movimentacao o) { return o.getDataMovimentacao().compareTo(getDataMovimentacao()); }
  • 56. I/O
  • 57. I/O Cuidados com I/O ( ) Você cuida dos recursos abertos por você try { writer.close(); } catch (Exception ex) { log.warning( String.format("Erro ao finalizar a escrita do arquivo de extrato: %s", ex) ); }
  • 58. I/O Cuidados com I/O ( ) Java é independente de plataforma, mas I/O não writer = new BufferedWriter( new OutputStreamWriter( new FileOutputStream(nomeArquivoExtrato), "utf-8“) );
  • 59. Obrigado! coders@bemobi.com.br

×