evento coders

60

Upload: diego-magalhaes

Post on 29-Jun-2015

238 views

Category:

Technology


4 download

DESCRIPTION

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.

TRANSCRIPT

Page 1: Evento CODERS
Page 2: Evento CODERS

Java Best Practices

Page 3: Evento CODERS

Classes e Interfaces

Page 4: Evento CODERS

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;

Page 5: Evento CODERS

Classes e Interfaces

Desacoplamento

{ } Evite ao máximo o acoplamento entre classes ou componentes

conta1.getExtratoFisico();

GeradorExtrato.geraExtratoFisico(conta1);

Page 6: Evento CODERS

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;

}

Page 7: Evento CODERS

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;

}

Page 8: Evento CODERS

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();

}

Page 9: Evento CODERS

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();

}

Page 10: Evento CODERS

Classes e Interfaces

Estáticos x Não Estáticos

{ } Prefira elementos estáticos a não estáticos

conta1.getExtratoFisico();

GeradorExtrato.geraExtratoFisico(conta1);

Page 11: Evento CODERS

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;

Page 12: Evento CODERS

Classes e Interfaces

Composição x Herança

{ } Prefira composição a herança

Page 13: Evento CODERS

Classes e Interfaces

Composição x Herança

{ } Prefira composição a herança

Page 14: Evento CODERS

Classes e Interfaces

Interfaces

{ } Use interface apenas para definição de tipos

public abstract class Cliente implements Bloqueavel, StatusCliente { public int status = ATIVO; // ...

}

Page 15: Evento CODERS

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

}

Page 16: Evento CODERS

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 { /** … */ }

Page 17: Evento CODERS

Métodos

Page 18: Evento CODERS

Métodos

Validação

< > Validação dos parâmetro da classe

public final void transfere(...) throws ... {// Validação dos parâmetros.ValidaParametrosDeTransferencia( ... );

}

Page 19: Evento CODERS

Métodos

Assinatura

< > Escolha corretamente as assinaturas de métodos

public abstract class Cliente implements Bloqueavel { // ...public abstract String getCliente(); // ...

}

Page 20: Evento CODERS

Métodos

Assinatura

< > Escolha corretamente as assinaturas de métodos

public abstract class Cliente implements Bloqueavel { // ...public abstract String getNome(); // ...

}

Page 21: Evento CODERS

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();

}

Page 22: Evento CODERS

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();

}

Page 23: Evento CODERS

Métodos

Javadoc

< > Lembre-se de documentar sempre seus métodos, especialmente os

métodos expostos em API’s

private void validaParametrosDePagamento( final Conta contaOrigem, final BigDecimal valorBoleto, final String codigoDeBarras )

throws IllegalArgumentException { ... }

Page 24: Evento CODERS

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

Page 25: Evento CODERS

Exceptions e Logging

Page 26: Evento CODERS

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) { } // ...

}

Page 27: Evento CODERS

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

} }

Page 28: Evento CODERS

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;

Page 29: Evento CODERS

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());

}

Page 30: Evento CODERS

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());

}

Page 31: Evento CODERS

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());

} }

Page 32: Evento CODERS

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

}

Page 33: Evento CODERS

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(); } // ...

}

Page 34: Evento CODERS

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); // ...

}

Page 35: Evento CODERS

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

}

Page 36: Evento CODERS

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;

Page 37: Evento CODERS

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

Page 38: Evento CODERS

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

Page 39: Evento CODERS

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

Page 40: Evento CODERS

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

Page 41: Evento CODERS

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

Page 42: Evento CODERS

Uso do Null

Page 43: Evento CODERS

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çãoconta2 = // ... código de inicialização

} catch (Exception e) { e.printStackTrace();

} log.info("realizando tranferencia da conta"

+ conta1.getNumeroConta() + " para "+ conta2.getNumeroConta());

Page 44: Evento CODERS

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

Page 45: Evento CODERS

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;

}

Page 46: Evento CODERS

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;

}

Page 47: Evento CODERS

Strings

Page 48: Evento CODERS

Strings

Criação de Strings

< > inicialização lenta

< > inicialização rápida

String msg = new String("O extrato foi gerado com sucesso“);Log.info(msg);

String msg = "O extrato foi gerado com sucesso“;Log.info(msg);

Page 49: Evento CODERS

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

Page 50: Evento CODERS

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

Page 51: Evento CODERS

Strings

Alteração de Strings

< > Use o operador ‘+’ se todos os operandos forem constantes

É transformado em:

String s = s1 + s2

String s = new StringBuilder(s1).append(s2).toString();

Page 52: Evento CODERS

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

}

Page 53: Evento CODERS

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();

}

Page 54: Evento CODERS

Collections

Page 55: Evento CODERS

Collections

Prefira coleções a classes antigas

[ ] Dê preferência as coleções do que ao Vector e HashTables

Page 56: Evento CODERS

Collections

Ordenação

[ ] Comparator e CompareTo

@Overridepublic int compareTo(Movimentacao o) { return o.getDataMovimentacao().compareTo(getDataMovimentacao());

}

Page 57: Evento CODERS

I/O

Page 58: Evento CODERS

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

}

Page 59: Evento CODERS

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“));