• Save
Técnicas de Refactorización (EN ESPANOL)
Upcoming SlideShare
Loading in...5
×
 

Técnicas de Refactorización (EN ESPANOL)

on

  • 278 views

 

Statistics

Views

Total Views
278
Views on SlideShare
268
Embed Views
10

Actions

Likes
1
Downloads
0
Comments
0

2 Embeds 10

http://www.agilecode.com.br 9
http://agilecode.com.br 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Técnicas de Refactorización (EN ESPANOL) Técnicas de Refactorización (EN ESPANOL) Presentation Transcript

  • Rodrigo Branas – @rodrigobranas - http://www.agilecode.com.br/es Técnicas de Refactorización
  • Rodrigo Branas rodrigo.branas@agilecode.com.br http://www.agilecode.com.br • • • • Desarrollo de Software en Gennera Entrenamientos en Agile Code Artículos en Java Magazine Conferencias sobre desarrollo de software en eventos, universidades y empresas
  • Formación Académica Ciencias de la Computación - UFSC Gestión de Proyectos - FGV Certificaciones SCJA, SCJP, SCJD, SCWCD, SCBCD, PMP, MCP e CSM Experiencia Desde hace más de 12 años desarrollando software en la plataforma Java en las empresas: EDS, HP, NET, Citibank, GM, Dígitro, Softplan, OnCast, Senai, VALE, RBS, Unimed, Globalcode, V.Office, Suntech, WPlex e Gennera.
  • Extraer Método
  • Hay un fragmento del código que podría ser agrupado para mejorar su comprensión. Transforme este fragmento en un nuevo método cuyo nombre expliqu su propósito.
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. public void exibirExtrato(Periodo periodo) { // imprimir cabeçalho System.out.println(“--------------------------------”); System.out.println(“EXTRATO – SANTANDER”); System.out.println(“--------------------------------”); // imprimir detalhes System.out.println(“NOME:” + nomeDoCliente); for(Lancto lancto : getLanctos(periodo)) { System.out.println(lancto); } System.out.println(“SALDO:” + saldoTotal); // imprimir rodapé System.out.println(“--------------------------------”); System.out.println(getDataEHoraAtual()); }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. public void exibirExtrato(Periodo periodo) { // imprimir cabeçalho System.out.println(“--------------------------------”); System.out.println(“EXTRATO – SANTANDER”); System.out.println(“--------------------------------”); // imprimir detalhes System.out.println(“NOME:” + nomeDoCliente); for(Lancto lancto : getLanctos(periodo)) { System.out.println(lancto); } System.out.println(“SALDO:” + saldoTotal); // imprimir rodapé System.out.println(“--------------------------------”); System.out.println(getDataEHoraAtual()); }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. public void exibirExtrato(Periodo periodo) { // imprimir cabeçalho // imprimir detalhes System.out.println(“NOME:” + nomeDoCliente); for(Lancto lancto : getLanctos(periodo)) { System.out.println(lancto); } System.out.println(“SALDO:” + saldoTotal); // imprimir rodapé System.out.println(“--------------------------------”); System.out.println(getDataEHoraAtual()); }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. public void exibirExtrato(Periodo periodo) { // imprimir cabeçalho imprimirCabecalho(); // imprimir detalhes System.out.println(“NOME:” + nomeDoCliente); for(Lancto lancto : getLanctos(periodo)) { System.out.println(lancto); } System.out.println(“SALDO:” + saldoTotal); // imprimir rodapé System.out.println(“--------------------------------”); System.out.println(getDataEHoraAtual()); }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. public void exibirExtrato(Periodo periodo) { // imprimir cabeçalho imprimirCabecalho(); // imprimir detalhes System.out.println(“NOME:” + nomeDoCliente); for(Lancto lancto : getLanctos(periodo)) { System.out.println(lancto); } System.out.println(“SALDO:” + saldoTotal); // imprimir rodapé System.out.println(“--------------------------------”); System.out.println(getDataEHoraAtual()); }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. public void exibirExtrato(Periodo periodo) { // imprimir cabeçalho imprimirCabecalho(); // imprimir detalhes // imprimir rodapé System.out.println(“--------------------------------”); System.out.println(getDataEHoraAtual()); }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. public void exibirExtrato(Periodo periodo) { // imprimir cabeçalho imprimirCabecalho(); // imprimir detalhes imprimirDetalhes(periodo); // imprimir rodapé System.out.println(“--------------------------------”); System.out.println(getDataEHoraAtual()); }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. public void exibirExtrato(Periodo periodo) { // imprimir cabeçalho imprimirCabecalho(); // imprimir detalhes imprimirDetalhes(periodo); // imprimir rodapé System.out.println(“--------------------------------”); System.out.println(getDataEHoraAtual()); }
  • 1. 2. 3. 4. 5. 6. 7. 8. public void exibirExtrato(Periodo periodo) { // imprimir cabeçalho imprimirCabecalho(); // imprimir detalhes imprimirDetalhes(periodo); // imprimir rodapé }
  • 1. 2. 3. 4. 5. 6. 7. 8. public void exibirExtrato(Periodo periodo) { // imprimir cabeçalho imprimirCabecalho(); // imprimir detalhes imprimirDetalhes(periodo); // imprimir rodapé imprimirRodape(); }
  • 1. 2. 3. 4. 5. 6. 7. 8. public void exibirExtrato(Periodo periodo) { imprimirCabecalho(); imprimirDetalhes(periodo); imprimirRodape(); }
  • 1. 2. 3. 4. 5. public void exibirExtrato(Periodo periodo) { imprimirCabecalho(); imprimirDetalhes(periodo); imprimirRodape(); }
  • 1. 2. 3. 4. 5. public void exibirExtrato(Periodo periodo) { imprimirCabecalho(); imprimirDetalhes(periodo); imprimirRodape(); }
  • Acceso directo en Eclipse: Shift + Alt + M
  • Internalizar Método
  • Su cuerpo es tan claro como su nombre. Ponga su cuerpo dentro del método que está llamando.
  • 1. 2. 3. 4. 5. 6. 7. int lerAvaliacao( ) { return (maisDeCincoAtrasos()) ? 2 : 1; } boolean maisDeCincoAtrasos() { return numeroDeAtrasos > 5; }
  • 1. 2. 3. 4. 5. 6. 7. int lerAvaliacao( ) { return (maisDeCincoAtrasos()) ? 2 : 1; } boolean maisDeCincoAtrasos() { return numeroDeAtrasos > 5; }
  • 1. 2. 3. 4. 5. 6. 7. int lerAvaliacao( ) { return () ? 2 : 1; } boolean maisDeCincoAtrasos() { return numeroDeAtrasos > 5; }
  • 1. 2. 3. 4. 5. 6. 7. int lerAvaliacao( ) { return (numeroDeAtrasos > 5) ? 2 : 1; } boolean maisDeCincoAtrasos() { return numeroDeAtrasos > 5; }
  • 1. 2. 3. int lerAvaliacao( ) { return (numeroDeAtrasos > 5) ? 2 : 1; }
  • Acceso directo en Eclipse: Shift + Alt + I
  • Internalizar Variable Temporal
  • Tu tienes una variable temporal que recibe una única atribución. Sustitua su referencia por la atribución.
  • 1. 2. 3. 4. boolean produtoCaro() { double preco = pedido.getPreco(); return preco > 1000; }
  • 1. 2. 3. 4. boolean produtoCaro() { double preco = pedido.getPreco(); return preco > 1000; }
  • 1. 2. 3. 4. boolean produtoCaro() { double preco = pedido.getPreco(); return > 1000; }
  • 1. 2. 3. 4. boolean produtoCaro() { double preco = pedido.getPreco(); return pedido.getPreco() > 1000; }
  • 1. 2. 3. 4. boolean produtoCaro() { double preco = pedido.getPreco(); return pedido.getPreco() > 1000; }
  • 1. 2. 3. boolean produtoCaro() { return pedido.getPreco() > 1000; }
  • Acceso directo en Eclipse: Shift + Alt + I
  • Introducir Variable Explicativa
  • Hay una expreción compleja. Pongala en una variable temporal cuyo su único objetivo es explicativo.
  • 1. 2. 3. 4. 5. 6. 7. double calculaValorDaCorrida() { if (hora > 22:00 || hora < 06:00) { return distancia * 3.90; } else { return distancia * 2.10; } }
  • 1. 2. 3. 4. 5. 6. 7. double calculaValorDaCorrida() { if () { return distancia * 3.90; } else { return distancia * 2.10; } }
  • 1. 2. 3. 4. 5. 6. 7. double calculaValorDaCorrida() { if (bandeiraDois) { return distancia * 3.90; } else { return distancia * 2.10; } }
  • 1. double calculaValorDaCorrida() { 2. boolean bandeiraDois = hora > 22:00 || hora < 06:00; 3. 4. 5. 6. 7. 8. if (bandeiraDois) { return distancia * 3.90; } else { return distancia * 2.10; } }
  • Acceso directo en Eclipse: Shift + Alt + L
  • Alternativa Es posible optar por la extración de un método para aumentar la possibilidad de reuso.
  • 1. 2. 3. 4. 5. 6. 7. double calculaValorDaCorrida() { if (hora > 22:00 || hora < 06:00) { return distancia * 3.90; } else { return distancia * 2.10; } }
  • 1. 2. 3. 4. 5. 6. 7. double calculaValorDaCorrida() { if () { return distancia * 3.90; } else { return distancia * 2.10; } }
  • 1. 2. 3. 4. 5. 6. 7. double calculaValorDaCorrida() { if (bandeiraDois()) { return distancia * 3.90; } else { return distancia * 2.10; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. double calculaValorDaCorrida() { if (bandeiraDois()) { return distancia * 3.90; } else { return distancia * 2.10; } } boolean bandeiraDois() { return hora > 22:00 || hora < 06:00; }
  • Acceso directo en Eclipse: Shift + Alt + M
  • Dividir Variable Temporal
  • Hay una variable temporal que recibe más de una atribución. Críe una variable para cada atribución.
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public class PoteDeWhey { int pesoDoPote; int pesoDaDose; int proteinasPorDose; double calcularPrecoPorProteina(double precoPote) { double temp = pesoDoPote / pesoDaDose; temp = temp * proteinasPorDose; temp = precoPote/temp; return temp; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public class PoteDeWhey { int pesoDoPote; int pesoDaDose; int proteinasPorDose; double calcularPrecoPorProteina(double precoPote) { double temp = pesoDoPote / pesoDaDose; temp = temp * proteinasPorDose; temp = precoPote/temp; return temp; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public class PoteDeWhey { int pesoDoPote; int pesoDaDose; int proteinasPorDose; double calcularPrecoPorProteina(double precoPote) { double = pesoDoPote / pesoDaDose; temp = * proteinasPorDose; temp = precoPote/temp; return temp; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public class PoteDeWhey { int pesoDoPote; int pesoDaDose; int proteinasPorDose; double calcularPrecoPorProteina(double precoPote) { double doses = pesoDoPote / pesoDaDose; temp = doses * proteinasPorDose; temp = precoPote/temp; return temp; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public class PoteDeWhey { int pesoDoPote; int pesoDaDose; int proteinasPorDose; double calcularPrecoPorProteina(double precoPote) { double doses = pesoDoPote / pesoDaDose; temp = doses * proteinasPorDose; temp = precoPote/temp; return temp; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public class PoteDeWhey { int pesoDoPote; int pesoDaDose; int proteinasPorDose; double calcularPrecoPorProteina(double precoPote) { double doses = pesoDoPote / pesoDaDose; = doses * proteinasPorDose; temp = precoPote/; return temp; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public class PoteDeWhey { int pesoDoPote; int pesoDaDose; int proteinasPorDose; double calcularPrecoPorProteina(double precoPote) { double doses = pesoDoPote / pesoDaDose; double proteinas = doses * proteinasPorDose; temp = precoPote/proteinas; return temp; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public class PoteDeWhey { int pesoDoPote; int pesoDaDose; int proteinasPorDose; double calcularPrecoPorProteina(double precoPote) { double doses = pesoDoPote / pesoDaDose; double proteinas = doses * proteinasPorDose; temp = precoPote/proteinas; return temp; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public class PoteDeWhey { int pesoDoPote; int pesoDaDose; int proteinasPorDose; double calcularPrecoPorProteina(double precoPote) { double doses = pesoDoPote / pesoDaDose; double proteinas = doses * proteinasPorDose; = precoPote/proteinas; return; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public class PoteDeWhey { int pesoDoPote; int pesoDaDose; int proteinasPorDose; double calcularPrecoPorProteina(double precoPote) { double doses = pesoDoPote / pesoDaDose; double proteinas = doses * proteinasPorDose; double precoPorProteina = precoPote/proteinas; return precoPorProteina; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. public class PoteDeWhey { int pesoDoPote; int pesoDaDose; int proteinasPorDose; double calcularPrecoPorProteina(double precoPote) { return getDoses()/getTotalProteinas(); }
  • Acesso directo en Eclipse: Shift + Alt + R
  • Eliminar Atribución a Parámetros
  • El código hace atribuciones a parámetros. Utilice una variable temporal en el lugar de la atribución.
  • 1. 2. 3. 4. 5. void desconto(Carrinho carrinho) { if (carrinho.getQuantidadeDeProdutos() > 50) { carrinho.setDesconto(0.10); } }
  • 1. 2. 3. 4. 5. void desconto(Carrinho carrinho) { if (carrinho.getQuantidadeDeProdutos() > 50) { carrinho.setDesconto(0.10); } }
  • 1. 2. 3. 4. 5. desconto(Carrinho carrinho) { if (carrinho.getQuantidadeDeProdutos() > 50) { carrinho.setDesconto(0.10); } }
  • 1. 2. 3. 4. 5. double desconto(Carrinho carrinho) { if (carrinho.getQuantidadeDeProdutos() > 50) { carrinho.setDesconto(0.10); } }
  • 1. 2. 3. 4. 5. double desconto(Carrinho carrinho) { if (carrinho.getQuantidadeDeProdutos() > 50) { } }
  • 1. 2. 3. 4. 5. double desconto(Carrinho carrinho) { if (carrinho.getQuantidadeDeProdutos() > 50) { return 0.10; } }
  • 1. 2. 3. 4. 5. 6. double desconto(Carrinho carrinho) { if (carrinho.getQuantidadeDeProdutos() > 50) { return 0.10; } }
  • 1. 2. 3. 4. 5. 6. double desconto(Carrinho carrinho) { if (carrinho.getQuantidadeDeProdutos() > 50) { return 0.10; } return 0.0; }
  • Sustituir Numeros Mágicos por Constantes
  • Hay un número con un significado especial. Críe una constante y nombre con su significado.
  • 1. 2. 3. 4. 5. 6. 7. public class Fisica { double energiaPotencial(double massa, double altura) { return massa * 9.81 * altura; } }
  • 1. 2. 3. 4. 5. 6. 7. public class Fisica { double energiaPotencial(double massa, double altura) { return massa * 9.81 * altura; } }
  • 1. 2. 3. 4. 5. 6. 7. public class Fisica { double energiaPotencial(double massa, double altura) { return massa * * altura; } }
  • 1. 2. 3. 4. 5. 6. 7. public class Fisica { double energiaPotencial(double massa, double altura) { return massa * GRAVIDADE * altura; } }
  • 1. 2. 3. 4. 5. 6. 7. public class Fisica { public static final double GRAVIDADE = 9.81; double energiaPotencial(double massa, double altura) { return massa * GRAVIDADE * altura; } }
  • Acceso directo en Eclipse: Ctrl + 3, Extract Constant
  • Renombrear Método
  • El nombre del método no está dejando claro su propósito. Altere el nombre del método.
  • 1. 2. 3. public void processar() { // Código para processar }
  • 1. 2. 3. public void () { // Código para processar }
  • 1. 2. 3. public void processarFolhaDePagamento() { // Código para processar folha de pagamento }
  • Acesso directo en Eclipse: Shift + Alt + R
  • Sustituir Algoritmo
  • El algoritmo es tan confuso que las refactorizaciones no están ayudando. Sustitua el corpo del método por un nuevo algoritmo.
  • Simplificando Expresiones Condicionales
  • Descompor Condicional
  • Hay una expresión condicional compleja. Extraer el contenido de cada una de las cláusulas para métodos.
  • 1. 2. 3. 4. 5. 6. 7. double calculaValorDaCorrida() { if (isBandeiraDois()) { return distancia * 3.90; } else { return distancia * 2.10; } }
  • 1. 2. 3. 4. 5. 6. 7. double calculaValorDaCorrida() { if (isBandeiraDois()) { return distancia * 3.90; } else { return distancia * 2.10; } }
  • 1. 2. 3. 4. 5. 6. 7. double calculaValorDaCorrida() { if (isBandeiraDois()) { } else { return distancia * 2.10; } }
  • 1. 2. 3. 4. 5. 6. 7. double calculaValorDaCorrida() { if (isBandeiraDois()) { return calcularBandeiraDois(distancia); } else { return distancia * 2.10; } }
  • 1. 2. 3. 4. 5. 6. 7. double calculaValorDaCorrida() { if (isBandeiraDois()) { return calcularBandeiraDois(distancia); } else { return distancia * 2.10; } }
  • 1. 2. 3. 4. 5. 6. 7. double calculaValorDaCorrida() { if (isBandeiraDois()) { return calcularBandeiraDois(distancia); } else { } }
  • 1. 2. 3. 4. 5. 6. 7. double calculaValorDaCorrida() { if (isBandeiraDois()) { return calcularBandeiraDois(distancia); } else { return calcularBandeiraUm(distancia); } }
  • 1. 2. 3. 4. 5. 6. 7. double calculaValorDaCorrida() { if (isBandeiraDois()) { return calcularBandeiraDois(distancia); } else { return calcularBandeiraUm(distancia); } }
  • 1. 2. 3. 4. 5. 6. double calculaValorDaCorrida() { if (isBandeiraDois()) { return calcularBandeiraDois(distancia); } return calcularBandeiraUm(distancia); }
  • 1. 2. 3. 4. 5. 6. double calculaValorDaCorrida() { if (isBandeiraDois()) { return calcularBandeiraDois(distancia); } return calcularBandeiraUm(distancia); }
  • Aceso directo en Eclipse: Shift + Alt + M
  • Consolidar Expresión Condicional
  • Hay una secuencia de pruebas condicionales. Consolidalas en una única expresión.
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. int calcularEntrada(int valor) { if (estudante) { if (temCarteirinha) { if (naoEhFalsa) { return valor * 0.5; } } } return valor; }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. int calcularEntrada(int valor) { if (estudante) { if (temCarteirinha) { return valor * 0.5; } } return valor; }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. int calcularEntrada(int valor) { if (estudante) { if (temCarteirinha && naoEhFalsa) { return valor * 0.5; } } return valor; }
  • 1. 2. 3. 4. 5. 6. 7. 8. int calcularEntrada(int valor) { if (estudante) { if (temCarteirinha && naoEhFalsa) { return valor * 0.5; } } return valor; }
  • 1. 2. 3. 4. 5. 6. 7. 8. int calcularEntrada(int valor) { if (estudante) { if (temCarteirinha && naoEhFalsa) { return valor * 0.5; } } return valor; }
  • 1. 2. 3. 4. 5. 6. 7. 8. int calcularEntrada(int valor) { if (estudante) { return valor * 0.5; } return valor; }
  • 1. 2. 3. 4. 5. 6. 7. 8. int calcularEntrada(int valor) { if (estudante && temCarteirinha && naoEhFalsa) { return valor * 0.5; } return valor; }
  • 1. 2. 3. 4. 5. 6. int calcularEntrada(int valor) { if (estudante && temCarteirinha && naoEhFalsa) { return valor * 0.5; } return valor; }
  • 1. 2. 3. 4. 5. 6. int calcularEntrada(int valor) { if (estudante && temCarteirinha && naoEhFalsa) { return valor * 0.5; } return valor; }
  • 1. 2. 3. 4. 5. 6. int calcularEntrada(int valor) { if () { return valor * 0.5; } return valor; }
  • 1. 2. 3. 4. 5. 6. int calcularEntrada(int valor) { if (aptoAPagarMeiaEntrada()) { return valor * 0.5; } return valor; }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. int calcularEntrada(int valor) { if (aptoAPagarMeiaEntrada()) { return valor * 0.5; } return valor; } boolean aptoAPagarMeiaEntrada() { return estudante && temCarteirinha && naoEhFalsa; }
  • 1. 2. 3. 4. 5. 6. 7. 8. int calcularEntrada(int valor) { if (aptoAPagarMeiaEntrada()) return valor * 0.5; return valor; } boolean aptoAPagarMeiaEntrada() { return estudante && temCarteirinha && naoEhFalsa; }
  • Consolidar Fragmentos Condicionales Duplicados
  • El mismo bloque de código aparece duplicado en ambas expresiones condicionales. Quite los a fuera.
  • 1. 2. 3. 4. 5. 6. 7. 8. public void sendRequest(Object data) { if (data == null) { resource.send(); } else { resource.setData(data); resource.send(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. public void sendRequest(Object data) { if (data == null) { resource.send(); } else { resource.setData(data); resource.send(); } }
  • 1. 2. 3. 4. 5. 6. public void sendRequest(Object data) { if (data == null) { } else { resource.setData(data); } }
  • 1. 2. 3. 4. 5. 6. 7. public void sendRequest(Object data) { if (data == null) { } else { resource.setData(data); } resource.send(); }
  • 1. 2. 3. 4. 5. 6. 7. public void sendRequest(Object data) { if (data != null) { } else { resource.setData(data); } resource.send(); }
  • 1. 2. 3. 4. 5. 6. public void sendRequest(Object data) { if (data != null) { resource.setData(data); } resource.send(); }
  • 1. 2. 3. 4. public void sendRequest(Object data) { if (data != null) resource.setData(data); resource.send(); }
  • Remover Condición Anidada por Cláusulas Guardia
  • Un método posee lógica condicional oscura. Sustituya la lógica oscura por cláusulasguardia.
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. public boolean fecharCaixa() { if(!caixaFechado) { if(saldo > 0) { if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } } else { throw new SaldoNegativoException(); } } else { return true; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. public boolean fecharCaixa() { if(!caixaFechado) { if(saldo > 0) { if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } } else { throw new SaldoNegativoException(); } } else { return true; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public boolean fecharCaixa() { if(!caixaFechado) { if(saldo > 0) { if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } } else { throw new SaldoNegativoException(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. public boolean fecharCaixa() { if(!caixaFechado) { } if(saldo > 0) { if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } } else { throw new SaldoNegativoException(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. public boolean fecharCaixa() { if(caixaFechado) { } if(saldo > 0) { if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } } else { throw new SaldoNegativoException(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. public boolean fecharCaixa() { if(caixaFechado) { return true; } if(saldo > 0) { if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } } else { throw new SaldoNegativoException(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo > 0) { if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } } else { throw new SaldoNegativoException(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo > 0) { if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } } else { throw new SaldoNegativoException(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo > 0) { if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } } else { throw new SaldoNegativoException(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo > 0) { if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } } else { throw new SaldoNegativoException(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo > 0) { if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo > 0) { } if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo < 0) { } if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo < 0) { throw new SaldoNegativoException(); } if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo < 0) throw new SaldoNegativoException(); if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo < 0) throw new SaldoNegativoException(); if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo < 0) throw new SaldoNegativoException(); if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo < 0) throw new SaldoNegativoException(); if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); } else { throw new DataRetroativaException(); } }
  • 1. 2. 3. 4. 5. 6. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo < 0) throw new SaldoNegativoException(); if (dataDeAberturaDoCaixa.equals(hoje)) { transferirDinheiroParaContaBancaria(saldo); }
  • 1. 2. 3. 4. 5. 6. 7. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo < 0) throw new SaldoNegativoException(); if (dataDeAberturaDoCaixa.equals(hoje)) { } transferirDinheiroParaContaBancaria(saldo); }
  • 1. 2. 3. 4. 5. 6. 7. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo < 0) throw new SaldoNegativoException(); if (!dataDeAberturaDoCaixa.equals(hoje)) { } transferirDinheiroParaContaBancaria(saldo); }
  • 1. 2. 3. 4. 5. 6. 7. 8. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo < 0) throw new SaldoNegativoException(); if (!dataDeAberturaDoCaixa.equals(hoje)) { throw new DataRetroativaException(); } transferirDinheiroParaContaBancaria(saldo); }
  • 1. 2. 3. 4. 5. 6. 7. 8. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo < 0) throw new SaldoNegativoException(); if () { throw new DataRetroativaException(); } transferirDinheiroParaContaBancaria(saldo); }
  • 1. 2. 3. 4. 5. 6. 7. 8. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo < 0) throw new SaldoNegativoException(); if (dataRetroativa) { throw new DataRetroativaException(); } transferirDinheiroParaContaBancaria(saldo); }
  • 1. 2. 3. 4. 5. 6. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo < 0) throw new SaldoNegativoException(); if (dataRetroativa) throw new DataRetroativaException(); transferirDinheiroParaContaBancaria(saldo); }
  • 1. 2. 3. 4. 5. 6. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo < 0) throw new SaldoNegativoException(); if (dataRetroativa) throw new DataRetroativaException(); transferirDinheiroParaContaBancaria(saldo); }
  • 1. 2. 3. 4. 5. 6. public boolean fecharCaixa() { if(caixaFechado) return true; if(saldo < 0) throw new SaldoNegativoException(); if (dataRetroativa) throw new DataRetroativaException(); transferirDinheiroParaContaBancaria(saldo); }
  • Sustituir Comando Condicional por Polimorfismo
  • Un comando condicional selecciona diferentes comportamientos según el tipo de objeto. Introduzca nuevas clases y mueva cada rama del comando condicional para un método.
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. public void emitirExtrato(String tipo) { if(tipo.equals(“SimplificadoMensal”)) { // Código para emissão do extrato simplificado mensal. } else if(tipo.equals(“SimplificadoQuinzenal”)) { // Código para emissão do extrato simplificado quinzenal. } else if(tipo.equals(“SimplificadoSemanal”)) { // Código para emissão do extrato simplificado semanal. } else if(tipo.equals(“Completo”)) { // Código para emissão do extrato completo. } }
  • Y si ubiera un nuevo tipo de extracto?
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. public void emitirExtrato(String tipo) { if(tipo.equals(“SimplificadoMensal”)) { // Código para emissão do extrato simplificado mensal. } else if(tipo.equals(“SimplificadoQuinzenal”)) { // Código para emissão do extrato simplificado quinzenal. } else if(tipo.equals(“SimplificadoSemanal”)) { // Código para emissão do extrato simplificado semanal. } else if(tipo.equals(“Completo”)) { // Código para emissão do extrato completo. } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. public void emitirExtrato(String tipo) { if(tipo.equals(“SimplificadoMensal”)) { // Código para emissão do extrato simplificado mensal. } else if(tipo.equals(“SimplificadoQuinzenal”)) { // Código para emissão do extrato simplificado quinzenal. } else if(tipo.equals(“SimplificadoSemanal”)) { // Código para emissão do extrato simplificado semanal. } else if(tipo.equals(“Completo”)) { // Código para emissão do extrato completo. } else if(tipo.equals(“CompletoTrimestral”)) { // Código para emissão do extrato completo trimestral. } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. public void emitirExtrato(String tipo) { if(tipo.equals(“SimplificadoMensal”)) { // Código para emissão do extrato simplificado mensal. } else if(tipo.equals(“SimplificadoQuinzenal”)) { // Código para emissão do extrato simplificado quinzenal. } else if(tipo.equals(“SimplificadoSemanal”)) { // Código para emissão do extrato simplificado semanal. } else if(tipo.equals(“Completo”)) { // Código para emissão do extrato completo. } else if(tipo.equals(“CompletoTrimestral”)) { // Código para emissão do extrato completo trimestral. } else if(tipo.equals(“CompletoAnual”)) { // Código para emissão do extrato completo anual. } }
  • Este método tiende al infinito...
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. public void emitirExtrato(String tipo) { if(tipo.equals(“SimplificadoMensal”)) { // Código para emissão do extrato simplificado mensal. } else if(tipo.equals(“SimplificadoQuinzenal”)) { // Código para emissão do extrato simplificado quinzenal. } else if(tipo.equals(“SimplificadoSemanal”)) { // Código para emissão do extrato simplificado semanal. } else if(tipo.equals(“Completo”)) { // Código para emissão do extrato completo. } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. public abstract class Extrato { public abstract void emitir(); } public class ExtratoSimplificadoMensal extends Extrato { public void emitir() { // Código para emissão do extrato simplificado mensal. } } public class ExtratoCompleto extends Extrato { public void emitir() { // Código para emissão do extrato completo. } }
  • 1. 2. 3. public void emitirExtrato(String tipo) { Extrato.criarExtrato(tipo).emitir(); }
  • Introducir Comando Ternario
  • Hay un comando condicional solamente para hacer una atribución. Utilice un comando ternário.
  • (expressão condicional) ? true : false;
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. public void calcularImposto(int valor) { int imposto = 0; if (valor > 1000) { imposto = valor * 0.05; } else { imposto = valor * 0.02; } return imposto; }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. public void calcularImposto(int valor) { int imposto = 0; if (valor > 1000) { imposto = valor * 0.05; } else { imposto = valor * 0.02; } return imposto; }
  • 1. 2. 3. 4. public void calcularImposto(int valor) { int imposto = return imposto; }
  • 1. 2. 3. 4. public void calcularImposto(int valor) { int imposto = (valor > 1000) ? valor * 0.05 : valor * 0.02; return imposto; }
  • 1. 2. 3. 4. public void calcularImposto(int valor) { int imposto = (valor > 1000) ? valor * 0.05 : valor * 0.02; return imposto; }
  • 1. 2. 3. public void calcularImposto(int valor) { return (valor > 1000) ? valor * 0.05 : valor * 0.02; }
  • Remover Comando Ternario
  • El ternario se quedó anidado y complejo. Cambie para un comando condicional.
  • 1. 2. 3. public void calcularImposto(int valor) { return (valor > 1000) ? (valor < 10000) ? valor * 0.05 : valor * 0.10 : valor * 0.02; }
  • Movendo Recursos entre Objetos
  • Ocultar Delegación
  • Una clase hace referencia a una otra, la cual hace referencia a una otra y así sucesivamente. Críe métodos para ocultar la delegación.
  • 1. 2. 3. 4. 5. 6. 7. // Código da classe PaperBoy… double valorAPagar = 2.00; if (cliente.getCarteira().getTotal() > valorAPagar) { cliente.getCarteira().retirarDinheiro(valorAPagar); } else { // Volte quando tiver dinheiro para pagar… }
  • 1. 2. 3. 4. 5. 6. 7. // Código da classe PaperBoy… double valorAPagar = 2.00; if (cliente.getCarteira().getTotal() > valorAPagar) { cliente.getCarteira().retirarDinheiro(valorAPagar); } else { // Volte quando tiver dinheiro para pagar… }
  • 1. 2. 3. 4. 5. 6. 7. // Código da classe PaperBoy… double valorAPagar = 2.00; if () { } else { // Volte quando tiver dinheiro para pagar… }
  • 1. 2. 3. 4. 5. 6. 7. // Código da classe PaperBoy… double valorAPagar = 2.00; if (cliente.pagar(valorAPagar)) { // Agradecemos a preferência… } else { // Volte quando tiver dinheiro para pagar… }
  • Encapsular Colección
  • Un método retorna una colección. Retorne solamente métodos que expongan el comportamiento relativo a colección.
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. ... Biblioteca biblioteca = new Biblioteca(); Set<Livro> livros = new HashSet<Livro>(); livros.add(new Livro(“Refactoring”); livros.add(new Livro(“Clean Code”); livros.add(new Livro(“Effective Java”); livros.add(new Livro(“Design Patterns”); biblioteca.setLivros(livros); ...
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public class Biblioteca { private Set<Livro> livros; public Set<Livro> getLivros() { return livros; } public void setLivros(Set<Livro> livros) { this.livros = livros; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public class Biblioteca { private Set<Livro> livros; public Set<Livro> getLivros() { return livros; } public void setLivros(Set<Livro> livros) { this.livros = livros; } }
  • 1. 2. 3. 4. 5. public class Biblioteca { private Set<Livro> livros; }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. public class Biblioteca { private Set<Livro> livros; public void adicionarLivro(Livro livro) { this.livros.add(livro); } public void removerLivro(Livro livro) { this.livros.remove(livro); }
  • 1. 2. 3. 4. 5. 6. 7. 8. ... Biblioteca biblioteca = new Biblioteca(); biblioteca.adicionarLivro(new Livro(“Refactoring”)); biblioteca.adicionarLivro(new Livro(“Clean Code”); biblioteca.adicionarLivro(new Livro(“Effective Java”); biblioteca.adicionarLivro(new Livro(“Design Patterns”); ...
  • Manejando Excepciones
  • ¿Como es la jerarquía de excepciones em Java?
  • Evite lanzar excepciones genéricas
  • 1. 2. 3. 4. 5. 6. public void calcularImposto(int salario) throws Exception { if(salario < 0) { throw new Exception(“Salário não pode ser negativo”); } // Código de cálculo do imposto retido na fonte }
  • 1. 2. 3. 4. 5. 6. public void calcularImposto(int salario) throws Exception { if(salario < 0) { throw new Exception(“Salário não pode ser negativo”); } // Código de cálculo do imposto retido na fonte }
  • 1. 2. 3. 4. 5. 6. public void calcularImposto(int salario) { if(salario < 0) { throw new (“Salário não pode ser negativo”); } // Código de cálculo do imposto retido na fonte }
  • 1. 2. 3. 4. 5. 6. public void calcularImposto(int salario) { if(salario < 0) { throw new IllegalArgumentException(“Salário não pode ser negativo”); } // Código de cálculo do imposto retido na fonte }
  • Evite atrapar excepciones de forma genérica
  • 1. 2. 3. 4. 5. try { // Código que lança a exceção. } catch (Exception e) { // Código de tratamento da exceção }
  • 1. 2. 3. 4. 5. try { // Código que lança a exceção. } catch (Throwable e) { // Código de tratamento da exceção }
  • No ignore excepciones
  • 1. 2. 3. 4. 5. try { // Código que lança a exceção. } catch (SomeException e) { // ??? }
  • 1. 2. 3. 4. 5. try { // Código que lança a exceção. } catch (SomeException e) { }
  • 1. 2. 3. 4. 5. try { // Código que lança a exceção. } catch (SomeException e) { e.printStacktrace(); }
  • Prefiera las excepciones que vienem por defecto en la lenguaje
  • Estamos utilizando una excepción customizada donde podríamos utilizar una excepción de la lenguaje. Sustitua al excepción customizada por una excepción de la lenguaje.
  • 1. 2. 3. 4. 5. 6. public void converterVideo(Video video) { if(video == null) { throw new VideoInvalidoException(); } // Código da conversão do video }
  • Principais exceções da linguagem: IllegalArgumentException IllegalStateException NullPointerException IndexOutOfBoundsException UnsupportedOperationException
  • 1. 2. 3. 4. 5. 6. public void converterVideo(Video video) { if(video == null) { throw new VideoInvalidoException(); } // Código da conversão do video }
  • 1. 2. 3. 4. 5. 6. public void converterVideo(Video video) { if(video == null) { throw new (); } // Código da conversão do video }
  • 1. 2. 3. 4. 5. 6. public void converterVideo(Video video) { if(video == null) { throw new IllegalArgumentException(); } // Código da conversão do video }
  • Substituir Código de Erro por Exceção
  • Un método retorna un código especial para indicar un error En cambio, genere una excepción
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. public class CaixaEletronico { public void pedidoDeSaque(double valor) { int resultado = banco.processarSaque(valor); if (resultado == 0) { dispensarDinheiro(valor); } else if (resultado == -1) { exibirMensagem(“Saldo Insuficiente”); } public class Banco { public int processarSaque(double valor) { if (valor <= saldo) { saldo -= valor; return 0; } else { return -1; } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. public class CaixaEletronico { public void pedidoDeSaque(double valor) { int resultado = banco.processarSaque(valor); if (resultado == 0) { dispensarDinheiro(valor); } else if (resultado == -1) { exibirMensagem(“Saldo Insuficiente”); } public class Banco { public int processarSaque(double valor) { if (valor <= saldo) { saldo -= valor; return 0; } else { return -1; } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. public class CaixaEletronico { public void pedidoDeSaque(double valor) { int resultado = banco.processarSaque(valor); if (resultado == 0) { dispensarDinheiro(valor); } else if (resultado == -1) { exibirMensagem(“Saldo Insuficiente”); } public class Banco { public processarSaque(double valor) { if (valor <= saldo) { saldo -= valor; return 0; } else { return -1; } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. public class CaixaEletronico { public void pedidoDeSaque(double valor) { int resultado = banco.processarSaque(valor); if (resultado == 0) { dispensarDinheiro(valor); } else if (resultado == -1) { exibirMensagem(“Saldo Insuficiente”); } public class Banco { public void processarSaque(double valor) { if (valor <= saldo) { saldo -= valor; return 0; } else { return -1; } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. public class CaixaEletronico { public void pedidoDeSaque(double valor) { int resultado = banco.processarSaque(valor); if (resultado == 0) { dispensarDinheiro(valor); } else if (resultado == -1) { exibirMensagem(“Saldo Insuficiente”); } public class Banco { public void processarSaque(double valor) { if (valor <= saldo) { saldo -= valor; return 0; } else { return -1; } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. public class CaixaEletronico { public void pedidoDeSaque(double valor) { int resultado = banco.processarSaque(valor); if (resultado == 0) { dispensarDinheiro(valor); } else if (resultado == -1) { exibirMensagem(“Saldo Insuficiente”); } public class Banco { public void processarSaque(double valor) { if (valor <= saldo) { saldo -= valor; } else { } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. public class CaixaEletronico { public void pedidoDeSaque(double valor) { int resultado = banco.processarSaque(valor); if (resultado == 0) { dispensarDinheiro(valor); } else if (resultado == -1) { exibirMensagem(“Saldo Insuficiente”); } public class Banco { public void processarSaque(double valor) { if (valor <= saldo) { saldo -= valor; } else { throw new SaldoInsuficienteException(); } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. public class CaixaEletronico { public void pedidoDeSaque(double valor) { int resultado = banco.processarSaque(valor); if (resultado == 0) { dispensarDinheiro(valor); } else if (resultado == -1) { exibirMensagem(“Saldo Insuficiente”); } public class Banco { public void processarSaque(double valor) throws SaldoInsuficienteEx... { if (valor <= saldo) { saldo -= valor; } else { throw new SaldoInsuficienteException(); } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. public class CaixaEletronico { public void pedidoDeSaque(double valor) { int resultado = banco.processarSaque(valor); if (resultado == 0) { dispensarDinheiro(valor); } else if (resultado == -1) { exibirMensagem(“Saldo Insuficiente”); } public class Banco { public void processarSaque(double valor) throws SaldoInsuficienteEx... { if (valor <= saldo) { saldo -= valor; } else { throw new SaldoInsuficienteException(); } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. public class CaixaEletronico { public void pedidoDeSaque(double valor) { banco.processarSaque(valor); dispensarDinheiro(valor); exibirMensagem(“Saldo Insuficiente”); } public class Banco { public void processarSaque(double valor) throws SaldoInsuficienteEx... { if (valor <= saldo) { saldo -= valor; } else { throw new SaldoInsuficienteException(); } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. public class CaixaEletronico { public void pedidoDeSaque(double valor) { try { banco.processarSaque(valor); dispensarDinheiro(valor); } catch(SaldoInsuficienteException e) { exibirMensagem(“Saldo Insuficiente”); } } public class Banco { public void processarSaque(double valor) throws SaldoInsuficienteEx... { if (valor <= saldo) { saldo -= valor; } else { throw new SaldoInsuficienteException(); } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. public class CaixaEletronico { public void pedidoDeSaque(double valor) { try { banco.processarSaque(valor); dispensarDinheiro(valor); } catch(SaldoInsuficienteException e) { exibirMensagem(“Saldo Insuficiente”); } } public class Banco { public void processarSaque(double valor) throws SaldoInsuficienteEx... { if (valor <= saldo) { saldo -= valor; } else { throw new SaldoInsuficienteException(); } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. public class CaixaEletronico { public void pedidoDeSaque(double valor) { try { banco.processarSaque(valor); dispensarDinheiro(valor); } catch(SaldoInsuficienteException e) { exibirMensagem(“Saldo Insuficiente”); } } public class Banco { public void processarSaque(double valor) throws SaldoInsuficienteEx... { if (valor > saldo) { saldo -= valor; } else { throw new SaldoInsuficienteException(); } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. public class CaixaEletronico { public void pedidoDeSaque(double valor) { try { banco.processarSaque(valor); dispensarDinheiro(valor); } catch(SaldoInsuficienteException e) { exibirMensagem(“Saldo Insuficiente”); } } public class Banco { public void processarSaque(double valor) throws SaldoInsuficienteEx... { if (valor > saldo) throw new SaldoInsuficienteException(); saldo -= valor; } }
  • Sustitua Excepción por Prueba
  • Estamos tratando una excepción en una condición en que podríamos hacer una prueba Haga la prueba primero.
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. public class ConnectionPool { private Stack available; public Connection getConnection() { Connection connection; try { connection = (Connection) available.pop(); return connection; } catch(EmptyStackException e) { connection = new Connection(); return connection; } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. public class ConnectionPool { private Stack available; public Connection getConnection() { Connection connection; try { connection = (Connection) available.pop(); return connection; } catch(EmptyStackException e) { connection = new Connection(); return connection; } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. public class ConnectionPool { private Stack available; public Connection getConnection() { Connection connection; try { connection = (Connection) available.pop(); return connection; } catch(EmptyStackException e) { connection = new Connection(); return connection; } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. public class ConnectionPool { private Stack available; public Connection getConnection() { Connection connection; if (available.isEmpty()) { } try { connection = (Connection) available.pop(); return connection; } catch(EmptyStackException e) { connection = new Connection(); return connection; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. public class ConnectionPool { private Stack available; public Connection getConnection() { Connection connection; if (available.isEmpty()) { connection = new Connection(); } try { connection = (Connection) available.pop(); return connection; } catch(EmptyStackException e) { return connection; } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. public class ConnectionPool { private Stack available; public Connection getConnection() { Connection connection; if (available.isEmpty()) { connection = new Connection(); return connection; } try { connection = (Connection) available.pop(); return connection; } catch(EmptyStackException e) { } } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. public class ConnectionPool { private Stack available; public Connection getConnection() { Connection connection; if (available.isEmpty()) { connection = new Connection(); return connection; } connection = (Connection) available.pop(); return connection; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. public class ConnectionPool { private Stack available; public Connection getConnection() { Connection connection; if (available.isEmpty()) { connection = new Connection(); return connection; } connection = (Connection) available.pop(); return connection; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. public class ConnectionPool { private Stack available; public Connection getConnection() { Connection connection; if (available.isEmpty()) { connection = new Connection(); return connection; } connection = (Connection) available.pop(); return connection; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public class ConnectionPool { private Stack available; public Connection getConnection() { Connection connection; if (available.isEmpty()) { return new Connection(); } connection = (Connection) available.pop(); return connection; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. public class ConnectionPool { private Stack available; public Connection getConnection() { Connection connection; if (available.isEmpty()) { return new Connection(); } return (Connection) available.pop(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. public class ConnectionPool { private Stack available; public Connection getConnection() { if (available.isEmpty()) { return new Connection(); } return (Connection) available.pop(); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. public class ConnectionPool { private Stack available; public Connection getConnection() { if (available.isEmpty()) return new Connection(); return (Connection) available.pop(); } }
  • 1. 2. 3. 4. 5. 6. 7. public class ConnectionPool { private Stack available; public Connection getConnection() { return (available.isEmpty()) ? new Connection() : (Connection) available.pop(); } }
  • Outras Refatorações
  • Sustituir Constructor por Método de Fábrica
  • Hay muchos constructores que hacen cosas distintas Utilice métodos de fábrica para hacer la construcción más intuitiva
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. public class Triangulo { private int lado1; private int lado2; private int lado3; public Triangulo(int tamanho) { this.lado1 = tamanho; this.lado2 = tamanho; this.lado3 = tamanho; } public Triangulo(int tamanho1, int tamanho2) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho2; } public Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. public class Triangulo { private int lado1; private int lado2; private int lado3; public Triangulo(int tamanho) { this.lado1 = tamanho; this.lado2 = tamanho; this.lado3 = tamanho; } public Triangulo(int tamanho1, int tamanho2) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } public Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. public class Triangulo { private int lado1; private int lado2; private int lado3; public Triangulo(int tamanho) { } public Triangulo(int tamanho1, int tamanho2) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } public Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. public class Triangulo { private int lado1; private int lado2; private int lado3; public Triangulo(int tamanho) { this(tamanho, tamanho, tamanho); } public Triangulo(int tamanho1, int tamanho2) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } public Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. public class Triangulo { private int lado1; private int lado2; private int lado3; public Triangulo(int tamanho) { this(tamanho, tamanho, tamanho); } public Triangulo(int tamanho1, int tamanho2) { } public Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. public class Triangulo { private int lado1; private int lado2; private int lado3; public Triangulo(int tamanho) { this(tamanho, tamanho, tamanho); } public Triangulo(int tamanho1, int tamanho2) { this(tamanho1, tamanho2, tamanho2); } public Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. public class Triangulo { private int lado1; private int lado2; private int lado3; public (int tamanho) { this(tamanho, tamanho, tamanho); } public Triangulo(int tamanho1, int tamanho2) { this(tamanho1, tamanho2, tamanho2); } public Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. public class Triangulo { private int lado1; private int lado2; private int lado3; public static criarTrianguloEquilatero(int tamanho) { this(tamanho, tamanho, tamanho); } public Triangulo(int tamanho1, int tamanho2) { this(tamanho1, tamanho2, tamanho2); } public Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. public class Triangulo { private int lado1; private int lado2; private int lado3; public static criarTrianguloEquilatero(int tamanho) { (tamanho, tamanho, tamanho); } public Triangulo(int tamanho1, int tamanho2) { this(tamanho1, tamanho2, tamanho2); } public Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. public class Triangulo { private int lado1; private int lado2; private int lado3; public static criarTrianguloEquilatero(int tamanho) { return new Triangulo(tamanho, tamanho, tamanho); } public Triangulo(int tamanho1, int tamanho2) { this(tamanho1, tamanho2, tamanho2); } public Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. public class Triangulo { private int lado1; private int lado2; private int lado3; public static criarTrianguloEquilatero(int tamanho) { return new Triangulo(tamanho, tamanho, tamanho); } public (int tamanho1, int tamanho2) { this(tamanho1, tamanho2, tamanho2); } public Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. public class Triangulo { private int lado1; private int lado2; private int lado3; public static criarTrianguloEquilatero(int tamanho) { return new Triangulo(tamanho, tamanho, tamanho); } public static criarTrianguloIsosceles(int tamanho1, int tamanho2) { this(tamanho1, tamanho2, tamanho2); } public Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. public class Triangulo { private int lado1; private int lado2; private int lado3; public static criarTrianguloEquilatero(int tamanho) { return new Triangulo(tamanho, tamanho, tamanho); } public static criarTrianguloIsosceles(int tamanho1, int tamanho2) { (tamanho1, tamanho2, tamanho2); } public Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. public class Triangulo { private int lado1; private int lado2; private int lado3; public static criarTrianguloEquilatero(int tamanho) { return new Triangulo(tamanho, tamanho, tamanho); } public static criarTrianguloIsosceles(int tamanho1, int tamanho2) { return new Triangulo(tamanho1, tamanho2, tamanho2); } public Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. public class Triangulo { private int lado1; private int lado2; private int lado3; public static criarTrianguloEquilatero(int tamanho) { return new Triangulo(tamanho, tamanho, tamanho); } public static criarTrianguloIsosceles(int tamanho1, int tamanho2) { return new Triangulo(tamanho1, tamanho2, tamanho2); } public static criarTrianguloEscaleno(int tamanho1, int tamanho2, int tamanho3) { return new Triangulo(tamanho1, tamanho2, tamanho3); } public Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. public class Triangulo { private int lado1; private int lado2; private int lado3; public static criarTrianguloEquilatero(int tamanho) { return new Triangulo(tamanho, tamanho, tamanho); } public static criarTrianguloIsosceles(int tamanho1, int tamanho2) { return new Triangulo(tamanho1, tamanho2, tamanho2); } public static criarTrianguloEscaleno(int tamanho1, int tamanho2, int tamanho3) { return new Triangulo(tamanho1, tamanho2, tamanho3); } public Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. public class Triangulo { private int lado1; private int lado2; private int lado3; public static criarTrianguloEquilatero(int tamanho) { return new Triangulo(tamanho, tamanho, tamanho); } public static criarTrianguloIsosceles(int tamanho1, int tamanho2) { return new Triangulo(tamanho1, tamanho2, tamanho2); } public static criarTrianguloEscaleno(int tamanho1, int tamanho2, int tamanho3) { return new Triangulo(tamanho1, tamanho2, tamanho3); } Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. public class Triangulo { private int lado1; private int lado2; private int lado3; public static Triangulo criarTrianguloEquilatero(int tamanho) { return new Triangulo(tamanho, tamanho, tamanho); } public static criarTrianguloIsosceles(int tamanho1, int tamanho2) { return new Triangulo(tamanho1, tamanho2, tamanho2); } public static criarTrianguloEscaleno(int tamanho1, int tamanho2, int tamanho3) { return new Triangulo(tamanho1, tamanho2, tamanho3); } private Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. public class Triangulo { private int lado1; private int lado2; private int lado3; public static criarTrianguloEquilatero(int tamanho) { return new Triangulo(tamanho, tamanho, tamanho); } public static criarTrianguloIsosceles(int tamanho1, int tamanho2) { return new Triangulo(tamanho1, tamanho2, tamanho2); } public static criarTrianguloEscaleno(int tamanho1, int tamanho2, int tamanho3) { return new Triangulo(tamanho1, tamanho2, tamanho3); } private Triangulo(int tamanho1, int tamanho2, int tamanho3) { this.lado1 = tamanho1; this.lado2 = tamanho2; this.lado3 = tamanho3; } }
  • Crear un Template Method
  • Dos métodos en subclasses distintas ejecutan pasos similares en la misma orden, pero los pasos son diferentes Utilice un Template Method para eliminar la duplicación
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. public class Cafe { public void fazerCafe() { ferverAgua(); passarCafe(); colocarNaXicara(); colocarAcucar(); } public void ferverAgua() { System.out.println(“Fervendo a água...”); } public void passarCafe() { System.out.println(“Passando o café...”); } public void colocaNaXicara() { System.out.println(“Colocando na xícara...”); } public void colocarAcucar() { System.out.println(“Colocando açucar...”); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. public class Cha { public void fazerCha() { ferverAgua(); mergulharCha(); colocarNaXicara(); colocarLimao(); } public void ferverAgua() { System.out.println(“Fervendo a água...”); } public void mergulharCha() { System.out.println(“Mergulhando o chá...”); } public void colocaNaXicara() { System.out.println(“Colocando na xícara...”); } public void colocarLimao() { System.out.println(“Colocando limão...”); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. public class Cafe { public void fazerCafe() { ferverAgua(); passarCafe(); colocarNaXicara(); colocarAcucar(); } public void ferverAgua() { System.out.println(“Fervendo a água...”); } public void passarCafe() { System.out.println(“Passando o café...”); } public void colocaNaXicara() { System.out.println(“Colocando na xícara...”); } public void colocarAcucar() { System.out.println(“Colocando açucar...”); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. public class Cha { public void fazerCha() { ferverAgua(); mergulharCha(); colocarNaXicara(); colocarLimao(); } public void ferverAgua() { System.out.println(“Fervendo a água...”); } public void mergulharCha() { System.out.println(“Mergulhando o chá...”); } public void colocaNaXicara() { System.out.println(“Colocando na xícara...”); } public void colocarLimao() { System.out.println(“Colocando limão...”); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. public abstract class BebidaQuente { public void prepararBebida() { ferverAgua(); infusao(); colocarNaXicara(); condimentar(); } public void ferverAgua() { System.out.println(“Fervendo a água...”); } public abstract void infusao(); public void colocaNaXicara() { System.out.println(“Colocando na xícara...”); } public abstract void condimentar(); }
  • 1. 2. 3. 4. 5. 6. 7. 8. public class Café extends BebidaQuente { public void infusao() { System.out.println(“Passando o café...”); } public void condimentar() { System.out.println(“Colocando açucar...”); } }
  • 1. 2. 3. 4. 5. 6. 7. 8. public class Cha extends BebidaQuente { public void infusao() { System.out.println(“Mergulhando o chá...”); } public void condimentar() { System.out.println(“Colocando limão...”); } }
  • Crear un Strategy Enum
  • Hay un comando switch o condicional anidado y no queremos crear un conjunto de clases Utilice un enum con strategy para absorber el polimorfismo
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. public class Banco { public void emitirExtrato(String tipo) { if(tipo.equals(“SimplificadoMensal”)) { // Código para emissão do extrato simplificado mensal. } else if(tipo.equals(“SimplificadoQuinzenal”)) { // Código para emissão do extrato simplificado quinzenal. } else if(tipo.equals(“SimplificadoSemanal”)) { // Código para emissão do extrato simplificado semanal. } else if(tipo.equals(“Completo”)) { // Código para emissão do extrato completo. } } }
  • 1. 2. 3. 4. 5. 6. public enum TipoExtrato { SimplificadoMensal, SimplificadoQuinzenal, SimplificadoSemanal, Completo; }
  • 1. 2. 3. 4. 5. 6. 7. 8. public enum TipoExtrato { SimplificadoMensal, SimplificadoQuinzenal, SimplificadoSemanal, Completo; public abstract void emitirExtrato(); }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. public enum TipoExtrato { SimplificadoMensal { public void emitirExtrato() { // Código da emissão do extrato. } }, SimplificadoQuinzenal, SimplificadoSemanal, Completo; public abstract void emitirExtrato(); }
  • 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. public class Banco { public void emitirExtrato(String tipo) { if(tipo.equals(“SimplificadoMensal”)) { // Código para emissão do extrato simplificado mensal. } else if(tipo.equals(“SimplificadoQuinzenal”)) { // Código para emissão do extrato simplificado quinzenal. } else if(tipo.equals(“SimplificadoSemanal”)) { // Código para emissão do extrato simplificado semanal. } else if(tipo.equals(“Completo”)) { // Código para emissão do extrato completo. } } }
  • 1. 2. 3. 4. 5. 6. public class Banco { public void emitirExtrato(String tipo) { } }
  • 1. 2. 3. 4. 5. 6. 7. public class Banco { public void emitirExtrato(String tipo) { TipoExtrato.valueOf(tipo).emitir(); } }
  • Fluent Interface
  • 1. 2. 3. 4. 5. 6. new EmailMessage() .from(“rodrigo.branas@gmail.com”) .to(“contato@globo.com”) .withSubject(“Fluent API - Demo”) .withMessage(“Message…”) .send();
  • 1. Date data = november(20, 2005);
  • 1. 2. 3. 4. 5. new Image(“cat.jpg”) .rotate(90) .watermark(“Copyright - 2012”) .blackAndWhite() .save(“catAfterChanges.jpg”);