SlideShare a Scribd company logo
1 of 60
Download to read offline
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
final
final
final

validaParametrosDePagamento(
Conta contaOrigem,
BigDecimal valorBoleto,
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ção
conta2 = // ... 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
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);
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
String s = s1 + s2

É transformado em:
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
@Override
public 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“)
);
Obrigado!
coders@bemobi.com.br

More Related Content

What's hot (19)

Java 13 Excecoes
Java 13 ExcecoesJava 13 Excecoes
Java 13 Excecoes
 
Tratamento de exceções em Java
Tratamento de exceções em JavaTratamento de exceções em Java
Tratamento de exceções em Java
 
Tratamento de exceções java
Tratamento de exceções   javaTratamento de exceções   java
Tratamento de exceções java
 
Tratamento de exceções em Java
Tratamento de exceções em JavaTratamento de exceções em Java
Tratamento de exceções em Java
 
Javascript para CSharpers 1 - Comparando
Javascript para CSharpers   1 - ComparandoJavascript para CSharpers   1 - Comparando
Javascript para CSharpers 1 - Comparando
 
Java11
Java11Java11
Java11
 
Java12
Java12Java12
Java12
 
Erros, exceções e asserções
Erros, exceções e asserçõesErros, exceções e asserções
Erros, exceções e asserções
 
JAVA - Tratamento de Erros
JAVA - Tratamento de ErrosJAVA - Tratamento de Erros
JAVA - Tratamento de Erros
 
Java hidden features
Java hidden featuresJava hidden features
Java hidden features
 
Ferramentas testes2003
Ferramentas testes2003Ferramentas testes2003
Ferramentas testes2003
 
Java14
Java14Java14
Java14
 
Java hidden features
Java hidden featuresJava hidden features
Java hidden features
 
Excecoes
ExcecoesExcecoes
Excecoes
 
Paradigmas de Linguagens de Programação - Tratamento de Exceções
Paradigmas de Linguagens de Programação - Tratamento de ExceçõesParadigmas de Linguagens de Programação - Tratamento de Exceções
Paradigmas de Linguagens de Programação - Tratamento de Exceções
 
Introdução a programação I
Introdução a programação IIntrodução a programação I
Introdução a programação I
 
Java recursos avançados - socket connection
Java   recursos avançados - socket connectionJava   recursos avançados - socket connection
Java recursos avançados - socket connection
 
Prog web 06-php-oo
Prog web 06-php-ooProg web 06-php-oo
Prog web 06-php-oo
 
Programação Concorrente - Gerenciamento de Threads - Parte II
Programação Concorrente - Gerenciamento de Threads - Parte IIProgramação Concorrente - Gerenciamento de Threads - Parte II
Programação Concorrente - Gerenciamento de Threads - Parte II
 

Similar to Java Best Practices Classes e Interfaces

Similar to Java Best Practices Classes e Interfaces (20)

JasperReports Tecnicas de geracao_de_relatorios1
JasperReports  Tecnicas de geracao_de_relatorios1JasperReports  Tecnicas de geracao_de_relatorios1
JasperReports Tecnicas de geracao_de_relatorios1
 
PrincipaiPrincipais Frameworks e Documentação
PrincipaiPrincipais Frameworks e DocumentaçãoPrincipaiPrincipais Frameworks e Documentação
PrincipaiPrincipais Frameworks e Documentação
 
Persistência com Realm.io
Persistência com Realm.ioPersistência com Realm.io
Persistência com Realm.io
 
PHP fora da Web
PHP fora da WebPHP fora da Web
PHP fora da Web
 
servlet-respostas
servlet-respostasservlet-respostas
servlet-respostas
 
Java
JavaJava
Java
 
Struts Cap10 DepuraçãO E Log
Struts Cap10 DepuraçãO E LogStruts Cap10 DepuraçãO E Log
Struts Cap10 DepuraçãO E Log
 
Algoritmos Aula 03
Algoritmos Aula 03Algoritmos Aula 03
Algoritmos Aula 03
 
Doctrine2 Seminário PHP
Doctrine2 Seminário PHPDoctrine2 Seminário PHP
Doctrine2 Seminário PHP
 
Tutorial java swing
Tutorial java swingTutorial java swing
Tutorial java swing
 
PHP FrameWARks - FISL
PHP FrameWARks - FISLPHP FrameWARks - FISL
PHP FrameWARks - FISL
 
Wicket 2008
Wicket 2008Wicket 2008
Wicket 2008
 
Programação Orientada por Objectos - Aula 6
Programação Orientada por Objectos - Aula 6Programação Orientada por Objectos - Aula 6
Programação Orientada por Objectos - Aula 6
 
Tw Course Ajax 2007 Ap05
Tw Course Ajax 2007 Ap05Tw Course Ajax 2007 Ap05
Tw Course Ajax 2007 Ap05
 
Curso de java 02
Curso de java 02Curso de java 02
Curso de java 02
 
ASP.Net Módulo 2
ASP.Net   Módulo 2ASP.Net   Módulo 2
ASP.Net Módulo 2
 
Spock Framework 2
Spock Framework 2Spock Framework 2
Spock Framework 2
 
As Novidades Do C# 4.0 - NetPonto
As Novidades Do C# 4.0 - NetPontoAs Novidades Do C# 4.0 - NetPonto
As Novidades Do C# 4.0 - NetPonto
 
Aula5
Aula5Aula5
Aula5
 
Programação Defensiva
Programação DefensivaProgramação Defensiva
Programação Defensiva
 

More from Diego Magalhães

More from Diego Magalhães (7)

X Bemobi Tech Talk - Maven
X Bemobi Tech Talk - MavenX Bemobi Tech Talk - Maven
X Bemobi Tech Talk - Maven
 
VIII TechTalk - Spring 3
VIII TechTalk - Spring 3VIII TechTalk - Spring 3
VIII TechTalk - Spring 3
 
II Bemobi Tech Talk - NoSQL
II Bemobi Tech Talk - NoSQLII Bemobi Tech Talk - NoSQL
II Bemobi Tech Talk - NoSQL
 
Comprafacil - Mobile Case
Comprafacil - Mobile CaseComprafacil - Mobile Case
Comprafacil - Mobile Case
 
Java Messaging Service
Java Messaging ServiceJava Messaging Service
Java Messaging Service
 
Botnet: Uma visao geral
Botnet: Uma visao geralBotnet: Uma visao geral
Botnet: Uma visao geral
 
Fowarder Receiver Pattern
Fowarder Receiver PatternFowarder Receiver Pattern
Fowarder Receiver Pattern
 

Java Best Practices Classes e Interfaces

  • 1.
  • 4. 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;
  • 5. Classes e Interfaces Desacoplamento { } Evite ao máximo o acoplamento entre classes ou componentes conta1.getExtratoFisico(); GeradorExtrato.geraExtratoFisico(conta1);
  • 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) { banco = new Banco(); } return banco; }
  • 7. 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; }
  • 8. 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(); }
  • 9. 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(); }
  • 10. Classes e Interfaces Estáticos x Não Estáticos { } Prefira elementos estáticos a não estáticos conta1.getExtratoFisico(); GeradorExtrato.geraExtratoFisico(conta1);
  • 11. 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;
  • 12. Classes e Interfaces Composição x Herança { } Prefira composição a herança
  • 13. Classes e Interfaces Composição x Herança { } Prefira composição a herança
  • 14. Classes e Interfaces Interfaces { } Use interface apenas para definição de tipos public abstract class Cliente implements Bloqueavel, StatusCliente { public int status = ATIVO; // ... }
  • 15. 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; // ... }
  • 16. 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 { /** … */ }
  • 18. Métodos Validação < > Validação dos parâmetro da classe public final void transfere(...) throws ... { // Validação dos parâmetros. ValidaParametrosDeTransferencia( ... ); }
  • 19. Métodos Assinatura < > Escolha corretamente as assinaturas de métodos public abstract class Cliente implements Bloqueavel { // ... public abstract String getCliente(); // ... }
  • 20. Métodos Assinatura < > Escolha corretamente as assinaturas de métodos public abstract class Cliente implements Bloqueavel { // ... public abstract String getNome(); // ... }
  • 21. 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(); }
  • 22. 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(); }
  • 23. 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 { ... }
  • 24. 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 { ... }
  • 26. 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) { } // ... }
  • 27. 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)); } }
  • 28. 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;
  • 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()); throw new Exception(e.getMessage()); }
  • 30. 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()); }
  • 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) { throw new Exception(e.getMessage()); } }
  • 32. 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)); } }
  • 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 Exception { validaParametrosDePagamento(contaOrigem, valorBoleto, codigoDeBarras); try { contaOrigem.sacar(valorBoleto); } catch (Exception e) { e.printStackTrace(); } // ... }
  • 34. 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); // ... }
  • 35. 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 ""; }
  • 36. 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;
  • 37. 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
  • 38. 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
  • 39. 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
  • 40. 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));
  • 41. 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
  • 43. 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());
  • 44. 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"); }
  • 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() { if (movimentacoes == null) return null; Collections.sort(movimentacoes); return movimentacoes; }
  • 46. 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; }
  • 48. 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);
  • 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.replaceAll("-",""); return "Conta{" + "agencia=" + ag + ", numeroConta=" + cc + '}'; }
  • 50. 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 + '}'; }
  • 51. 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();
  • 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(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++; }
  • 53. 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(); }
  • 55. Collections Prefira coleções a classes antigas [ ] Dê preferência as coleções do que ao Vector e HashTables
  • 56. Collections Ordenação [ ] Comparator e CompareTo @Override public int compareTo(Movimentacao o) { return o.getDataMovimentacao().compareTo(getDataMovimentacao()); }
  • 57. I/O
  • 58. 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) ); }
  • 59. 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“) );