Evento CODERS
-
Upload
diego-magalhaes -
Category
Technology
-
view
233 -
download
4
description
Transcript of Evento CODERS
Java Best Practices
Classes e Interfaces
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;
Classes e Interfaces
Desacoplamento
{ } Evite ao máximo o acoplamento entre classes ou componentes
conta1.getExtratoFisico();
GeradorExtrato.geraExtratoFisico(conta1);
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;
}
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;
}
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();
}
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();
}
Classes e Interfaces
Estáticos x Não Estáticos
{ } Prefira elementos estáticos a não estáticos
conta1.getExtratoFisico();
GeradorExtrato.geraExtratoFisico(conta1);
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;
Classes e Interfaces
Composição x Herança
{ } Prefira composição a herança
Classes e Interfaces
Composição x Herança
{ } Prefira composição a herança
Classes e Interfaces
Interfaces
{ } Use interface apenas para definição de tipos
public abstract class Cliente implements Bloqueavel, StatusCliente { public int status = ATIVO; // ...
}
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; // ...
}
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 { /** … */ }
Métodos
Métodos
Validação
< > Validação dos parâmetro da classe
public final void transfere(...) throws ... {// Validação dos parâmetros.ValidaParametrosDeTransferencia( ... );
}
Métodos
Assinatura
< > Escolha corretamente as assinaturas de métodos
public abstract class Cliente implements Bloqueavel { // ...public abstract String getCliente(); // ...
}
Métodos
Assinatura
< > Escolha corretamente as assinaturas de métodos
public abstract class Cliente implements Bloqueavel { // ...public abstract String getNome(); // ...
}
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();
}
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();
}
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 { ... }
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 { ... }
Exceptions e Logging
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) { } // ...
}
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));
} }
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;
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());
}
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());
}
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());
} }
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)); }
}
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(); } // ...
}
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); // ...
}
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 "";
}
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;
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
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
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
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));
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
Uso do Null
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());
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"); }
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;
}
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;
}
Strings
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);
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 + '}'; }
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 + '}'; }
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();
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++;
}
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();
}
Collections
Collections
Prefira coleções a classes antigas
[ ] Dê preferência as coleções do que ao Vector e HashTables
Collections
Ordenação
[ ] Comparator e CompareTo
@Overridepublic int compareTo(Movimentacao o) { return o.getDataMovimentacao().compareTo(getDataMovimentacao());
}
I/O
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));
}
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“));