SlideShare uma empresa Scribd logo
IF BOM É IF MORTO
Refatoração de código com o pattern Strategy
Jackson Veroneze - jackson@jacksonveroneze.com
Mario Mendonça - mario.mendonca@gmail.com
Cenário Imagine que o Governo possua um sistema que calcula
o valor dos impostos de receitas vindas de diversas
fontes.
Codificação
public class CalculadorDeImpostos {
public double calculaImposto(double receita, String
tipoDeImposto) {
double imposto = 0;
if (tipoDeImposto.equals("IPI"))
imposto = receita * 0.15;
else if (tipoDeImposto.equals("ISS"))
imposto = receita * 0.06;
else if (tipoDeImposto.equals("ICMS"))
imposto = receita * 0.08;
return imposto;
}
}
Problema Enorme quantidade de IFs que a classe possui.
Tende a crescer à medida que novos impostos vão
sendo criados, gerando mais complexidade ao código.
Problema
public class CalculadorDeImpostos {
public double calculaImposto(double receita, String tipoDeImposto) {
double imposto = 0;
if (tipoDeImposto.equals("IPI"))
imposto = receita * 0.15;
else if (tipoDeImposto.equals("ISS"))
imposto = receita * 0.06;
else if (tipoDeImposto.equals("ICMS"))
imposto = receita * 0.08;
else if (tipoDeImposto.equals("IR"))
imposto = receita * 0.03;
else if (tipoDeImposto.equals("IOF"))
imposto = receita * 0.02;
else if (tipoDeImposto.equals("IPVA"))
imposto = receita * 0.05;
else if (tipoDeImposto.equals("CPMF"))
imposto = receita * 0.03;
else if (tipoDeImposto.equals("IPTU"))
imposto = receita * 0.07;
else if (tipoDeImposto.equals("ITR"))
imposto = receita * 0.07;
return imposto;
}
}
IF BOM É IF MORTO
Questionamento - "Mas se não posso usar nem IF, nem Switch-Case,
nem nada parecido, COMO é que vou tratar isso?"
Strategy, a salvação
SOLUÇÃO
SOLUÇÃO O padrão Strategy permite que você crie novos objetos
(ex: "IPTU", "IPVA", etc) de um mesmo grupo (ex:
"Impostos"), sem alterar a classe com a qual opera (ex:
"Calculador de Impostos").
1º passo public interface Imposto {
double calculaImposto(double receita);
}
2º passo
public class IPI implements Imposto {
public double calculaImposto(double receita) {
return receita * 0.15;
}
}
public class ISS implements Imposto {
public double calculaImposto(double receita) {
return receita * 0.06;
}
}
public class ICMS implements Imposto {
public double calculaImposto(double receita) {
return receita * 0.08;
}
}
3º passo public class CalculadorDeImpostos {
public double calculaImposto(double receita,
Imposto imposto) {
return imposto.calculaImposto(receita);
}
}
Teste do padrão
package br.eti.arquiteturacomputacional;
public class RealizaBalancoFinanceiro {
public static void main(String[] args) {
CalculadorDeImpostos calculador = new CalculadorDeImpostos();
//Calcula o imposto ICMS
Imposto icms = new ICMS();
double impostoAReceber = calculador.calculaImposto(500, icms);
System.out.println("ICMS de 500 = " + impostoAReceber);
//Calcula o imposto ISS
Imposto iss = new ISS();
impostoAReceber = calculador.calculaImposto(500, iss);
System.out.println("ISS de 500 = " + impostoAReceber);
}
}
Conclusão Podemos criar novos impostos, sem alterar qualquer
código existente. Esse padrão chama-se Strategy
porque entregamos uma estratégia (um imposto
especializado) para um contexto
(CalculadorDeImpostos).
if ($iPanamnese->getDeTpresposta() == 'O') {
$opcoes = explode(';', $iPanamnese->getDeOpcoes());
for ($x = 0; $x < count($opcoes); $x++)
$vlr[$x] = $opcoes[($x)];
$resposta = isset($values['campo' . $iPanamnese->getId()]) ?
vlr[$values['campo' . $iPanamnese->getId()]] : '';
$ranamneseI->setDeResposta($resposta);
} elseif ($iPanamnese->getDeTpresposta() == 'M') {
$opcoes = explode(';', $iPanamnese->getDeOpcoes());
for ($x = 0; $x < count($opcoes); $x++)
$vlr[$x] = $opcoes[($x)];
$resp = '0';
if (isset($values['campo' . $iPanamnese->getId()])) {
$tmp = $values['campo' . $iPanamnese->getId()];
if (is_array($tmp)) {
foreach ($tmp as $opcao)
$resp .= $vlr[$opcao] . ';';
$resp = substr($resp, 0, strlen($resp) - 1);
} else {
$resp = 'NDA';
}
}
$ranamneseI->setDeResposta($resp);
} elseif ($iPanamnese->getDeTpresposta() == 'R') {
$resp = '0';
if (isset($values['campo' . $iPanamnese->getId()])) {
$opcoes = explode(';', $iPanamnese->getDeOpcoes());
if (isset($values['campo' . $iPanamnese->getId()])) {
$resp = $opcoes[$values['campo' . $iPanamnese->getId()]];
}
}
$ranamneseI->setDeResposta($resp);
} elseif ($iPanamnese->getDeTpresposta() == 'V' || $iPanamnese->getDeTpresposta() == 'D' ||
$iPanamnese->getDeTpresposta() == 'N') {
if (isset($values['campo' . $iPanamnese->getId()])) {
$ranamneseI->setDeResposta($values['campo' . $iPanamnese->getId()]);
}
}
Referências http://www.arquiteturacomputacional.eti.br/2013/02/p
adrao-de-projeto-strategy.html
http://marconems.blogspot.com.br/2010/06/if-bom-e-
if-morto.html

Mais conteúdo relacionado

Semelhante a If bom é if morto

01_EntradaESaida-1283dcca0a544b38a2df92fceb9d98e2.pdf
01_EntradaESaida-1283dcca0a544b38a2df92fceb9d98e2.pdf01_EntradaESaida-1283dcca0a544b38a2df92fceb9d98e2.pdf
01_EntradaESaida-1283dcca0a544b38a2df92fceb9d98e2.pdftrabalhocasa3
 
ProgramaçãO Com Threads – CóDigo Fonte “Conta BancáRia Conjunta”
ProgramaçãO Com Threads – CóDigo Fonte “Conta BancáRia Conjunta”ProgramaçãO Com Threads – CóDigo Fonte “Conta BancáRia Conjunta”
ProgramaçãO Com Threads – CóDigo Fonte “Conta BancáRia Conjunta”mauriciopel
 
ProgramaçãO Com Threads – CóDigo Fonte “Conta BancáRia Conjunta”
ProgramaçãO Com Threads – CóDigo Fonte “Conta BancáRia Conjunta”ProgramaçãO Com Threads – CóDigo Fonte “Conta BancáRia Conjunta”
ProgramaçãO Com Threads – CóDigo Fonte “Conta BancáRia Conjunta”mauriciopel
 
Artesanato de software
Artesanato de softwareArtesanato de software
Artesanato de softwareEdson Yanaga
 
Combatendo code smells em aplicações Java
Combatendo code smells em aplicações JavaCombatendo code smells em aplicações Java
Combatendo code smells em aplicações JavaEmmanuel Neri
 
Exercícios java 20 02
Exercícios java 20   02Exercícios java 20   02
Exercícios java 20 02julyesersantos
 
Estruturas em C++ (struct)
Estruturas em C++ (struct)Estruturas em C++ (struct)
Estruturas em C++ (struct)Márcio Rizzatto
 

Semelhante a If bom é if morto (10)

01 strategy
01 strategy01 strategy
01 strategy
 
01_EntradaESaida-1283dcca0a544b38a2df92fceb9d98e2.pdf
01_EntradaESaida-1283dcca0a544b38a2df92fceb9d98e2.pdf01_EntradaESaida-1283dcca0a544b38a2df92fceb9d98e2.pdf
01_EntradaESaida-1283dcca0a544b38a2df92fceb9d98e2.pdf
 
Dip the dependency inversion principle
Dip   the dependency inversion principleDip   the dependency inversion principle
Dip the dependency inversion principle
 
ProgramaçãO Com Threads – CóDigo Fonte “Conta BancáRia Conjunta”
ProgramaçãO Com Threads – CóDigo Fonte “Conta BancáRia Conjunta”ProgramaçãO Com Threads – CóDigo Fonte “Conta BancáRia Conjunta”
ProgramaçãO Com Threads – CóDigo Fonte “Conta BancáRia Conjunta”
 
ProgramaçãO Com Threads – CóDigo Fonte “Conta BancáRia Conjunta”
ProgramaçãO Com Threads – CóDigo Fonte “Conta BancáRia Conjunta”ProgramaçãO Com Threads – CóDigo Fonte “Conta BancáRia Conjunta”
ProgramaçãO Com Threads – CóDigo Fonte “Conta BancáRia Conjunta”
 
Artesanato de software
Artesanato de softwareArtesanato de software
Artesanato de software
 
SAP Impostos MM.pdf
SAP Impostos MM.pdfSAP Impostos MM.pdf
SAP Impostos MM.pdf
 
Combatendo code smells em aplicações Java
Combatendo code smells em aplicações JavaCombatendo code smells em aplicações Java
Combatendo code smells em aplicações Java
 
Exercícios java 20 02
Exercícios java 20   02Exercícios java 20   02
Exercícios java 20 02
 
Estruturas em C++ (struct)
Estruturas em C++ (struct)Estruturas em C++ (struct)
Estruturas em C++ (struct)
 

Mais de Mario Mendonça

Integração contínua - Prática de desenvolvimento
Integração contínua - Prática de desenvolvimentoIntegração contínua - Prática de desenvolvimento
Integração contínua - Prática de desenvolvimentoMario Mendonça
 
Gulp - Automatizador de tarefas de front-end
Gulp - Automatizador de tarefas de front-endGulp - Automatizador de tarefas de front-end
Gulp - Automatizador de tarefas de front-endMario Mendonça
 
Web socket - Trazendo soquetes para a web
Web socket - Trazendo soquetes para a webWeb socket - Trazendo soquetes para a web
Web socket - Trazendo soquetes para a webMario Mendonça
 
Web Storage - Armazenamento de dados
Web Storage - Armazenamento de dadosWeb Storage - Armazenamento de dados
Web Storage - Armazenamento de dadosMario Mendonça
 

Mais de Mario Mendonça (8)

Integração contínua - Prática de desenvolvimento
Integração contínua - Prática de desenvolvimentoIntegração contínua - Prática de desenvolvimento
Integração contínua - Prática de desenvolvimento
 
JWT - Json Web Token
JWT - Json Web TokenJWT - Json Web Token
JWT - Json Web Token
 
Gulp - Automatizador de tarefas de front-end
Gulp - Automatizador de tarefas de front-endGulp - Automatizador de tarefas de front-end
Gulp - Automatizador de tarefas de front-end
 
Web socket - Trazendo soquetes para a web
Web socket - Trazendo soquetes para a webWeb socket - Trazendo soquetes para a web
Web socket - Trazendo soquetes para a web
 
Web Storage - Armazenamento de dados
Web Storage - Armazenamento de dadosWeb Storage - Armazenamento de dados
Web Storage - Armazenamento de dados
 
Vanilla JS
Vanilla JSVanilla JS
Vanilla JS
 
Web components
Web componentsWeb components
Web components
 
Progressive Web Apps
Progressive Web AppsProgressive Web Apps
Progressive Web Apps
 

If bom é if morto

  • 1. IF BOM É IF MORTO Refatoração de código com o pattern Strategy Jackson Veroneze - jackson@jacksonveroneze.com Mario Mendonça - mario.mendonca@gmail.com
  • 2. Cenário Imagine que o Governo possua um sistema que calcula o valor dos impostos de receitas vindas de diversas fontes.
  • 3. Codificação public class CalculadorDeImpostos { public double calculaImposto(double receita, String tipoDeImposto) { double imposto = 0; if (tipoDeImposto.equals("IPI")) imposto = receita * 0.15; else if (tipoDeImposto.equals("ISS")) imposto = receita * 0.06; else if (tipoDeImposto.equals("ICMS")) imposto = receita * 0.08; return imposto; } }
  • 4. Problema Enorme quantidade de IFs que a classe possui. Tende a crescer à medida que novos impostos vão sendo criados, gerando mais complexidade ao código.
  • 5. Problema public class CalculadorDeImpostos { public double calculaImposto(double receita, String tipoDeImposto) { double imposto = 0; if (tipoDeImposto.equals("IPI")) imposto = receita * 0.15; else if (tipoDeImposto.equals("ISS")) imposto = receita * 0.06; else if (tipoDeImposto.equals("ICMS")) imposto = receita * 0.08; else if (tipoDeImposto.equals("IR")) imposto = receita * 0.03; else if (tipoDeImposto.equals("IOF")) imposto = receita * 0.02; else if (tipoDeImposto.equals("IPVA")) imposto = receita * 0.05; else if (tipoDeImposto.equals("CPMF")) imposto = receita * 0.03; else if (tipoDeImposto.equals("IPTU")) imposto = receita * 0.07; else if (tipoDeImposto.equals("ITR")) imposto = receita * 0.07; return imposto; } }
  • 6. IF BOM É IF MORTO
  • 7. Questionamento - "Mas se não posso usar nem IF, nem Switch-Case, nem nada parecido, COMO é que vou tratar isso?"
  • 10. SOLUÇÃO O padrão Strategy permite que você crie novos objetos (ex: "IPTU", "IPVA", etc) de um mesmo grupo (ex: "Impostos"), sem alterar a classe com a qual opera (ex: "Calculador de Impostos").
  • 11. 1º passo public interface Imposto { double calculaImposto(double receita); }
  • 12. 2º passo public class IPI implements Imposto { public double calculaImposto(double receita) { return receita * 0.15; } } public class ISS implements Imposto { public double calculaImposto(double receita) { return receita * 0.06; } } public class ICMS implements Imposto { public double calculaImposto(double receita) { return receita * 0.08; } }
  • 13. 3º passo public class CalculadorDeImpostos { public double calculaImposto(double receita, Imposto imposto) { return imposto.calculaImposto(receita); } }
  • 14. Teste do padrão package br.eti.arquiteturacomputacional; public class RealizaBalancoFinanceiro { public static void main(String[] args) { CalculadorDeImpostos calculador = new CalculadorDeImpostos(); //Calcula o imposto ICMS Imposto icms = new ICMS(); double impostoAReceber = calculador.calculaImposto(500, icms); System.out.println("ICMS de 500 = " + impostoAReceber); //Calcula o imposto ISS Imposto iss = new ISS(); impostoAReceber = calculador.calculaImposto(500, iss); System.out.println("ISS de 500 = " + impostoAReceber); } }
  • 15. Conclusão Podemos criar novos impostos, sem alterar qualquer código existente. Esse padrão chama-se Strategy porque entregamos uma estratégia (um imposto especializado) para um contexto (CalculadorDeImpostos).
  • 16. if ($iPanamnese->getDeTpresposta() == 'O') { $opcoes = explode(';', $iPanamnese->getDeOpcoes()); for ($x = 0; $x < count($opcoes); $x++) $vlr[$x] = $opcoes[($x)]; $resposta = isset($values['campo' . $iPanamnese->getId()]) ? vlr[$values['campo' . $iPanamnese->getId()]] : ''; $ranamneseI->setDeResposta($resposta); } elseif ($iPanamnese->getDeTpresposta() == 'M') { $opcoes = explode(';', $iPanamnese->getDeOpcoes()); for ($x = 0; $x < count($opcoes); $x++) $vlr[$x] = $opcoes[($x)]; $resp = '0'; if (isset($values['campo' . $iPanamnese->getId()])) { $tmp = $values['campo' . $iPanamnese->getId()]; if (is_array($tmp)) { foreach ($tmp as $opcao) $resp .= $vlr[$opcao] . ';'; $resp = substr($resp, 0, strlen($resp) - 1); } else { $resp = 'NDA'; } } $ranamneseI->setDeResposta($resp); } elseif ($iPanamnese->getDeTpresposta() == 'R') { $resp = '0'; if (isset($values['campo' . $iPanamnese->getId()])) { $opcoes = explode(';', $iPanamnese->getDeOpcoes()); if (isset($values['campo' . $iPanamnese->getId()])) { $resp = $opcoes[$values['campo' . $iPanamnese->getId()]]; } } $ranamneseI->setDeResposta($resp); } elseif ($iPanamnese->getDeTpresposta() == 'V' || $iPanamnese->getDeTpresposta() == 'D' || $iPanamnese->getDeTpresposta() == 'N') { if (isset($values['campo' . $iPanamnese->getId()])) { $ranamneseI->setDeResposta($values['campo' . $iPanamnese->getId()]); } }