SlideShare une entreprise Scribd logo
1  sur  27
Srp
Ocp
Lsp
Isp
Dip
SRP - Single Responsibility Principle
public class CalculadoraDeSalario {
public double calcula(Funcionario funcionario) {
if(DESENVOLVEDOR.equals(funcionario.getCargo())) {
return dezOuVintePorCento(funcionario);
}
if (DBA.equals(funcionario.getCargo()) ||
TESTER.equals(funcionario.getCargo())) {
return quinzeOuVinteCincoPorCento(funcionario);
}
throw new RuntimeException("Funcionário Inválido");
}
private double quinzeOuVinteCincoPorCento(Funcionario funcionario) {
if(funcionario.getSalarioBase() > 2000) {
return funcionario.getSalarioBase() * 0.75;
} else {
return funcionario.getSalarioBase() * 0.85;
}
}
private double dezOuVintePorCento(Funcionario funcionario) {
if(funcionario.getSalarioBase() > 3000) {
return funcionario.getSalarioBase() * 0.8;
} else {
return funcionario.getSalarioBase() * 0.9;
}
}
}
public class CalculadoraDeSalario
(m) double calcula(Funcionario)
public class Funcionario
// mais campos
(f) Cargo cargo;
(f) double salarioBase;
(m) double calculaSalario;
public enum Cargo {
DESENVOLVEDOR(new DezOuVintePorCento()),
DBA(new QuinzeOuVinteCincoPorCento()),
TESTER(new QuinzeOuVinteCincoPorCento());
(f) RegraDeCalculo regra;
(c) Cargo(RegraDeCalculo regra) this.regra = regra;
(m) RegraDeCalculo getRegra
public interface RegraDeCalculo
(m) double calcula(Funcionario)
public double calculaSalario() {
return cargo.getRegra().calcula(this);
}
OCP - Open/Closed Principle
- Aberta para extensão
- Fechada para modificação
LSP - Liskov Substitutive Principle
- Classes derivadas devem ser substituíveis por suas
classes bases
- Deve-se pensar muito nas pré-condições e pós-condições
ISP - Interface Segregation Principle
- Clientes não devem ser forçados a depender de métodos
que não usam
DIP - Dependency Inversion Principle
- Dependa sempre de abstração, não de implementação
Don’t repeat yourself - Não repetir código, movendo partes
que precisam ser reutilizadas para métodos ou classes.
WET -
“Write Everything Twice”
“We Enjoy Typing”
“Waste Everyone’s Time”
DRY
KISS
Keep It Simple, Stupid
private static String semana(int dia) {
switch (dia){
case 1:
return "Segunda-feira";
case 2:
return "Terça-feira";
case 3:
return "Quarta-feira";
case 4:
return "Quinta-feira";
case 5:
return "Sexta-feira";
case 6:
return "Sabado";
case 7:
return "Domingo";
default:
throw new IllegalArgumentException("Dia
inválido: Somente números entre 1 e 7");
}
}
private static String semana(int dia) {
if(dia < 1 || dia > 7) throw new
IllegalArgumentException("Dia inválido: Somente
números entre 1 e 7");
String[] diasDaSemana = {
"Segunda-feira",
"Terça-feira",
"Quarta-feira",
"Quinta-feira",
"Sexta-feira",
"Sábado",
"Domingo"
};
return diasDaSemana[dia - 1];
}
API Best Practices
1) HTTP aplicado a REST
- Conhecer bem a base
2) Não retorne texto puro
- Passar o content-type!
3) Evite usar verbos nas URIs
- Metodos HTTP devem ser suficiente para
descrever a ação
4) Use plurais nos recursos
- É preferível o uso de plurais para garantir a
padronização
GET /loja/listaClientes/
GET /loja/clientes/
GET /loja/cliente/1
GET /loja/clientes/
GET /loja/clientes/
POST /loja/clientes/
5) Retorne detalhes dos erros no body
- Retornar detalhes de erros ajuda a fazer o
debug
6) Retorne StatusCodes significativos
{
“error” : “Email inválido”
“detail” : {
“surname” :
“...”
}
}
HTTP/1.1 200 OK
Content-Type: text/html
{
"status": "failure",
"data": {
"error": "Nome é obrigatório"
}
}
7) Use StatusCode consistentemente
- Use um padrão
- Retorne sempre o mesmo StatusCode para
aquele tipo de requisição
8) Evite Nested Resources
- Pode ficar confuso
- Prefira QueryParams
GET /pacientes/5/prontuario
GET /prontuarios/?paciente_id=5
9) Lide com barras finais 10) Use QueryParams para filtros e paginação
POST /pacientes
POST /pacientes/
GET /artigos/?page=8&size=10
GET /artigos/revisados
GET /artigos/?revisados=true&page=5&size=10
Style Guide - Java
Um conjunto de regras para padronizar a escrita do código,
regendo desde a identação do código até a criação do Javadoc
Algumas regras
Segundo o Google JavaStryleGuide: https://google.github.io/styleguide/javaguide.html
- Estrutura do arquivo-fonte;
- Caracteres especiais
- Formatação;
- Nomenclatura;
Design Patterns
Strategy
- Separa os algoritmos para alcançar a reusabilidade
- Permite selecionar um algoritmo durante a execução
Contexto
<<interface>>
Estratégia
+executa()
Estratégia
1
+executa()
Estratégia
2
+executa()
public class CalculadoraDeImpostos {
public void realizaCalculo(Orcamento orcamento, String imposto) {
if(imposto.equals("ICMS")) System.out.println(orcamento.getValor() * 0.1);
else if (imposto.equals("ISS")) System.out.println(orcamento.getValor() * 0.06);
// else if mais um
// else if e outro
// else if continua crescendo
// else if não para
}
}
public class CalculadoraDeImpostos {
public void realizaCalculoICMS(Orcamento orcamento) {
System.out.println(new ICMS().calculaICMS(orcamento));
}
public void realizaCalculoISS(Orcamento orcamento) {
System.out.println(new ISS().calculaISS(orcamento));
}
// E mais um método
// E outro
// E aqui mais um
}
public class CalculadoraDeImpostos {
public void realizaCalculo(Orcamento orcamento, Imposto
imposto) {
System.out.println(imposto.calcula(orcamento));
}
}
public interface Imposto {
double calcula(Orcamento orcamento);
}
public class ICMS implements Imposto {
@Override
public double calcula(Orcamento orcamento) {
return orcamento.getValor() * 0.1;
}
}
public class ISS implements Imposto {
@Override
public double calcula(Orcamento orcamento) {
return orcamento.getValor() * 0.06;
}
}
public class TesteCalculadora {
public static void main(String[] args) {
Orcamento orcamento = new Orcamento(500);
var calculadora = new CalculadoraDeImpostos();
System.out.println("******* ICMS *********");
calculadora.realizaCalculo(orcamento, new ICMS());
System.out.println("******* ISS *********");
calculadora.realizaCalculo(orcamento, new ISS());
}
}
State
- Permite alterar o comportamento baseado no estado interno do objeto
<<interface>>
Estado
+acao1()
+ação2()
Estado 1
+acao1()
+acao2()
Estado 2
+acao1()
+acao2()
Contexto
+metodo()
estado;
public class Orcamento {
private double valor;
private List<Item> itens;
public Orcamento(double valor) {
this.valor = valor;
this.itens = new ArrayList<Item>();
}
public double getValor() { return valor; }
public void desconta(double valor) {
this.valor -= valor;
}
public List<Item> getItens() {
return Collections.unmodifiableList(itens);
}
public void adicionaItem(Item item) {
itens.add(item);
}
}
public class Orcamento {
public static final int EM_APROVACAO = 1;
public static final int APROVADO = 2;
public static final int REPROVADO = 3;
public static final int FINALIZADO = 4;
private double valor;
private List<Item> itens;
private int estadoAtual;
// resto da classe escondida porque não cabia mais na tela
public void aplicaDescontoExtra() {
if(estadoAtual == EM_APROVACAO) valor = valor - (valor * 0.05);
else if(estadoAtual == APROVADO) valor = valor - (valor * 0.02);
else throw new RuntimeException("Orçamentos reprovados não
recebem desconto extra!");
}
}
public class Orcamento {
private double valor;
private List<Item> itens;
private EstadoAtualDeUmOrcamento estadoAtual;
public Orcamento(double valor) {
this.valor = valor;
this.itens = new ArrayList<Item>();
this.estadoAtual = new EmAprovacao();
}
// resto da classe porque não cabia mais na tela
public void aplicaDescontoExtra() {
estadoAtual.aplicaDescontoExtra(this);
}
}
Em Aprovação
Aprovado Reprovado
Finalizado
public class Orcamento {
// resto da classe porque não cabia mais na tela
public void
alteraEstado(EstadoAtualDeUmOrcamento
novoEstado) {
this.estadoAtual = novoEstado;
}
public void aprova() {
estadoAtual.aprova(this);
}
public void reprova() {
estadoAtual.reprova(this);
}
public void finaliza() {
estadoAtual.finaliza(this);
}
}
public interface EstadoAtualDeUmOrcamento {
void aplicaDescontoExtra(Orcamento orcamento);
void aprova(Orcamento orcamento);
void reprova(Orcamento orcamento);
void finaliza(Orcamento orcamento);
}
public class EmAprovacao implements EstadoAtualDeUmOrcamento {
@Override
public void aplicaDescontoExtra(Orcamento orcamento) {
orcamento.desconta(orcamento.getValor() * 0.05); }
@Override
public void aprova(Orcamento orcamento) {
orcamento.alteraEstado(new Aprovado()); }
@Override
public void reprova(Orcamento orcamento) {
orcamento.alteraEstado(new Reprovado());}
@Override
public void finaliza(Orcamento orcamento) {
throw new IllegalStateException("Orçamentos em aprovação não
podem ser finalizados"); }
}

Contenu connexe

Tendances

Object Calisthenics: relaxe e escreva códigos simples
Object Calisthenics: relaxe e escreva códigos simplesObject Calisthenics: relaxe e escreva códigos simples
Object Calisthenics: relaxe e escreva códigos simples
Otávio Calaça Xavier
 
Criando APIs usando o micro-framework Respect
Criando APIs usando o micro-framework RespectCriando APIs usando o micro-framework Respect
Criando APIs usando o micro-framework Respect
Ivan Rosolen
 
LabMM4 (T13 - 12/13) - Funções
LabMM4 (T13 - 12/13) - FunçõesLabMM4 (T13 - 12/13) - Funções
LabMM4 (T13 - 12/13) - Funções
Carlos Santos
 
Acesso a banco de dados com JDBC
Acesso a banco de dados com JDBCAcesso a banco de dados com JDBC
Acesso a banco de dados com JDBC
Eduardo Mendes
 
Sql Server Stored Procedures
Sql Server   Stored ProceduresSql Server   Stored Procedures
Sql Server Stored Procedures
alexdutra
 

Tendances (20)

Spring Capitulo 03
Spring Capitulo 03Spring Capitulo 03
Spring Capitulo 03
 
Bd sql (1)
Bd sql (1)Bd sql (1)
Bd sql (1)
 
PHP FrameWARks - FISL
PHP FrameWARks - FISLPHP FrameWARks - FISL
PHP FrameWARks - FISL
 
Introdução ao Respect\Validation (1.0)
Introdução ao Respect\Validation (1.0)Introdução ao Respect\Validation (1.0)
Introdução ao Respect\Validation (1.0)
 
Sql - Comandos dml do mysql - parte 1
Sql - Comandos dml do mysql - parte 1Sql - Comandos dml do mysql - parte 1
Sql - Comandos dml do mysql - parte 1
 
Código legado - PHP Conference Brasil - 2014
Código legado - PHP Conference Brasil - 2014Código legado - PHP Conference Brasil - 2014
Código legado - PHP Conference Brasil - 2014
 
um breve treinamento sobre SQL e suas funcionalidades
um breve treinamento sobre SQL e suas funcionalidadesum breve treinamento sobre SQL e suas funcionalidades
um breve treinamento sobre SQL e suas funcionalidades
 
Lidando com desafios dos microserviços com a stack Spring Cloud Netflix
Lidando com desafios dos microserviços com a stack Spring Cloud NetflixLidando com desafios dos microserviços com a stack Spring Cloud Netflix
Lidando com desafios dos microserviços com a stack Spring Cloud Netflix
 
Object Calisthenics: relaxe e escreva códigos simples
Object Calisthenics: relaxe e escreva códigos simplesObject Calisthenics: relaxe e escreva códigos simples
Object Calisthenics: relaxe e escreva códigos simples
 
Palestra Novidades da linguagem C# 6
Palestra Novidades da linguagem C# 6Palestra Novidades da linguagem C# 6
Palestra Novidades da linguagem C# 6
 
Da Argila Ao Forte - Como desenvolver uma loja virtual
Da Argila Ao Forte - Como desenvolver uma loja virtualDa Argila Ao Forte - Como desenvolver uma loja virtual
Da Argila Ao Forte - Como desenvolver uma loja virtual
 
Utilizando views, stored procedures e triggers
Utilizando views, stored procedures e triggersUtilizando views, stored procedures e triggers
Utilizando views, stored procedures e triggers
 
Desenvolvimento de um CRUD utilizando Stored Procedure
Desenvolvimento de um CRUD utilizando Stored ProcedureDesenvolvimento de um CRUD utilizando Stored Procedure
Desenvolvimento de um CRUD utilizando Stored Procedure
 
Sql proficiente
Sql proficienteSql proficiente
Sql proficiente
 
Criando APIs usando o micro-framework Respect
Criando APIs usando o micro-framework RespectCriando APIs usando o micro-framework Respect
Criando APIs usando o micro-framework Respect
 
LabMM4 (T13 - 12/13) - Funções
LabMM4 (T13 - 12/13) - FunçõesLabMM4 (T13 - 12/13) - Funções
LabMM4 (T13 - 12/13) - Funções
 
Acesso a banco de dados com JDBC
Acesso a banco de dados com JDBCAcesso a banco de dados com JDBC
Acesso a banco de dados com JDBC
 
Sql Server Stored Procedures
Sql Server   Stored ProceduresSql Server   Stored Procedures
Sql Server Stored Procedures
 
Acesso a Banco de Dados em Java usando JDBC
Acesso a Banco de Dados em Java usando JDBCAcesso a Banco de Dados em Java usando JDBC
Acesso a Banco de Dados em Java usando JDBC
 
Triggers no SQL Server
Triggers no SQL ServerTriggers no SQL Server
Triggers no SQL Server
 

Similaire à Design patterns

LabMM3 - Aula teórica 09
LabMM3 - Aula teórica 09LabMM3 - Aula teórica 09
LabMM3 - Aula teórica 09
Carlos Santos
 
(A11) LabMM3 - JavaScript - Subalgoritmos e scope
(A11) LabMM3 - JavaScript - Subalgoritmos e scope(A11) LabMM3 - JavaScript - Subalgoritmos e scope
(A11) LabMM3 - JavaScript - Subalgoritmos e scope
Carlos Santos
 
Spring + Tapestry Um novo paradigma de desenvolvimento web
Spring + Tapestry Um novo paradigma de desenvolvimento webSpring + Tapestry Um novo paradigma de desenvolvimento web
Spring + Tapestry Um novo paradigma de desenvolvimento web
elliando dias
 

Similaire à Design patterns (20)

Como conectar programas em linguagem java a bases de dados
Como conectar programas em linguagem java  a bases de dadosComo conectar programas em linguagem java  a bases de dados
Como conectar programas em linguagem java a bases de dados
 
Evento Front End SP - Organizando o Javascript
 Evento Front End SP - Organizando o Javascript Evento Front End SP - Organizando o Javascript
Evento Front End SP - Organizando o Javascript
 
Play Framework - FLISOL
Play Framework - FLISOLPlay Framework - FLISOL
Play Framework - FLISOL
 
SOLID - Os cinco princípios ágeis de POO
SOLID - Os cinco princípios ágeis de POOSOLID - Os cinco princípios ágeis de POO
SOLID - Os cinco princípios ágeis de POO
 
De a máxima cobertura nos seus testes de API
De a máxima cobertura nos seus testes de APIDe a máxima cobertura nos seus testes de API
De a máxima cobertura nos seus testes de API
 
Javascript Ilegível
Javascript IlegívelJavascript Ilegível
Javascript Ilegível
 
Refatoração de código com Capitão Nascimento versão completa
Refatoração de código com Capitão Nascimento versão completaRefatoração de código com Capitão Nascimento versão completa
Refatoração de código com Capitão Nascimento versão completa
 
LabMM3 - Aula teórica 09
LabMM3 - Aula teórica 09LabMM3 - Aula teórica 09
LabMM3 - Aula teórica 09
 
TDC2016SP - Trilha Node.Js
TDC2016SP - Trilha Node.JsTDC2016SP - Trilha Node.Js
TDC2016SP - Trilha Node.Js
 
Vraptor
VraptorVraptor
Vraptor
 
Ganhando tempo com casos de testes
Ganhando tempo com casos de testesGanhando tempo com casos de testes
Ganhando tempo com casos de testes
 
Qualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnitQualidade no desenvolvimento de software com PHPUnit
Qualidade no desenvolvimento de software com PHPUnit
 
Web 2.0 e AJAX - Parte 2 / 3
Web 2.0 e AJAX - Parte 2 / 3Web 2.0 e AJAX - Parte 2 / 3
Web 2.0 e AJAX - Parte 2 / 3
 
VRaptor4
VRaptor4VRaptor4
VRaptor4
 
Cuso Ruby - Aula 05 - Testes com RSpec
Cuso Ruby - Aula 05 - Testes com RSpecCuso Ruby - Aula 05 - Testes com RSpec
Cuso Ruby - Aula 05 - Testes com RSpec
 
(A11) LabMM3 - JavaScript - Subalgoritmos e scope
(A11) LabMM3 - JavaScript - Subalgoritmos e scope(A11) LabMM3 - JavaScript - Subalgoritmos e scope
(A11) LabMM3 - JavaScript - Subalgoritmos e scope
 
Spring + Tapestry Um novo paradigma de desenvolvimento web
Spring + Tapestry Um novo paradigma de desenvolvimento webSpring + Tapestry Um novo paradigma de desenvolvimento web
Spring + Tapestry Um novo paradigma de desenvolvimento web
 
Design OO
Design OODesign OO
Design OO
 
Ecosistema spring a_plataforma_enterprise_jav
Ecosistema spring a_plataforma_enterprise_javEcosistema spring a_plataforma_enterprise_jav
Ecosistema spring a_plataforma_enterprise_jav
 
Rafael Garcia - Yii Framework, principais características e em ação
Rafael Garcia - Yii Framework, principais características e em açãoRafael Garcia - Yii Framework, principais características e em ação
Rafael Garcia - Yii Framework, principais características e em ação
 

Design patterns

  • 2. SRP - Single Responsibility Principle
  • 3. public class CalculadoraDeSalario { public double calcula(Funcionario funcionario) { if(DESENVOLVEDOR.equals(funcionario.getCargo())) { return dezOuVintePorCento(funcionario); } if (DBA.equals(funcionario.getCargo()) || TESTER.equals(funcionario.getCargo())) { return quinzeOuVinteCincoPorCento(funcionario); } throw new RuntimeException("Funcionário Inválido"); } private double quinzeOuVinteCincoPorCento(Funcionario funcionario) { if(funcionario.getSalarioBase() > 2000) { return funcionario.getSalarioBase() * 0.75; } else { return funcionario.getSalarioBase() * 0.85; } } private double dezOuVintePorCento(Funcionario funcionario) { if(funcionario.getSalarioBase() > 3000) { return funcionario.getSalarioBase() * 0.8; } else { return funcionario.getSalarioBase() * 0.9; } } }
  • 4. public class CalculadoraDeSalario (m) double calcula(Funcionario) public class Funcionario // mais campos (f) Cargo cargo; (f) double salarioBase; (m) double calculaSalario; public enum Cargo { DESENVOLVEDOR(new DezOuVintePorCento()), DBA(new QuinzeOuVinteCincoPorCento()), TESTER(new QuinzeOuVinteCincoPorCento()); (f) RegraDeCalculo regra; (c) Cargo(RegraDeCalculo regra) this.regra = regra; (m) RegraDeCalculo getRegra public interface RegraDeCalculo (m) double calcula(Funcionario) public double calculaSalario() { return cargo.getRegra().calcula(this); }
  • 5. OCP - Open/Closed Principle - Aberta para extensão - Fechada para modificação
  • 6. LSP - Liskov Substitutive Principle - Classes derivadas devem ser substituíveis por suas classes bases - Deve-se pensar muito nas pré-condições e pós-condições
  • 7. ISP - Interface Segregation Principle - Clientes não devem ser forçados a depender de métodos que não usam
  • 8. DIP - Dependency Inversion Principle - Dependa sempre de abstração, não de implementação
  • 9. Don’t repeat yourself - Não repetir código, movendo partes que precisam ser reutilizadas para métodos ou classes. WET - “Write Everything Twice” “We Enjoy Typing” “Waste Everyone’s Time” DRY
  • 11. private static String semana(int dia) { switch (dia){ case 1: return "Segunda-feira"; case 2: return "Terça-feira"; case 3: return "Quarta-feira"; case 4: return "Quinta-feira"; case 5: return "Sexta-feira"; case 6: return "Sabado"; case 7: return "Domingo"; default: throw new IllegalArgumentException("Dia inválido: Somente números entre 1 e 7"); } } private static String semana(int dia) { if(dia < 1 || dia > 7) throw new IllegalArgumentException("Dia inválido: Somente números entre 1 e 7"); String[] diasDaSemana = { "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado", "Domingo" }; return diasDaSemana[dia - 1]; }
  • 12. API Best Practices 1) HTTP aplicado a REST - Conhecer bem a base 2) Não retorne texto puro - Passar o content-type!
  • 13. 3) Evite usar verbos nas URIs - Metodos HTTP devem ser suficiente para descrever a ação 4) Use plurais nos recursos - É preferível o uso de plurais para garantir a padronização GET /loja/listaClientes/ GET /loja/clientes/ GET /loja/cliente/1 GET /loja/clientes/ GET /loja/clientes/ POST /loja/clientes/
  • 14. 5) Retorne detalhes dos erros no body - Retornar detalhes de erros ajuda a fazer o debug 6) Retorne StatusCodes significativos { “error” : “Email inválido” “detail” : { “surname” : “...” } } HTTP/1.1 200 OK Content-Type: text/html { "status": "failure", "data": { "error": "Nome é obrigatório" } }
  • 15. 7) Use StatusCode consistentemente - Use um padrão - Retorne sempre o mesmo StatusCode para aquele tipo de requisição 8) Evite Nested Resources - Pode ficar confuso - Prefira QueryParams GET /pacientes/5/prontuario GET /prontuarios/?paciente_id=5
  • 16. 9) Lide com barras finais 10) Use QueryParams para filtros e paginação POST /pacientes POST /pacientes/ GET /artigos/?page=8&size=10 GET /artigos/revisados GET /artigos/?revisados=true&page=5&size=10
  • 17. Style Guide - Java Um conjunto de regras para padronizar a escrita do código, regendo desde a identação do código até a criação do Javadoc
  • 18. Algumas regras Segundo o Google JavaStryleGuide: https://google.github.io/styleguide/javaguide.html - Estrutura do arquivo-fonte; - Caracteres especiais - Formatação; - Nomenclatura;
  • 20. Strategy - Separa os algoritmos para alcançar a reusabilidade - Permite selecionar um algoritmo durante a execução Contexto <<interface>> Estratégia +executa() Estratégia 1 +executa() Estratégia 2 +executa()
  • 21. public class CalculadoraDeImpostos { public void realizaCalculo(Orcamento orcamento, String imposto) { if(imposto.equals("ICMS")) System.out.println(orcamento.getValor() * 0.1); else if (imposto.equals("ISS")) System.out.println(orcamento.getValor() * 0.06); // else if mais um // else if e outro // else if continua crescendo // else if não para } }
  • 22. public class CalculadoraDeImpostos { public void realizaCalculoICMS(Orcamento orcamento) { System.out.println(new ICMS().calculaICMS(orcamento)); } public void realizaCalculoISS(Orcamento orcamento) { System.out.println(new ISS().calculaISS(orcamento)); } // E mais um método // E outro // E aqui mais um }
  • 23. public class CalculadoraDeImpostos { public void realizaCalculo(Orcamento orcamento, Imposto imposto) { System.out.println(imposto.calcula(orcamento)); } } public interface Imposto { double calcula(Orcamento orcamento); } public class ICMS implements Imposto { @Override public double calcula(Orcamento orcamento) { return orcamento.getValor() * 0.1; } } public class ISS implements Imposto { @Override public double calcula(Orcamento orcamento) { return orcamento.getValor() * 0.06; } } public class TesteCalculadora { public static void main(String[] args) { Orcamento orcamento = new Orcamento(500); var calculadora = new CalculadoraDeImpostos(); System.out.println("******* ICMS *********"); calculadora.realizaCalculo(orcamento, new ICMS()); System.out.println("******* ISS *********"); calculadora.realizaCalculo(orcamento, new ISS()); } }
  • 24. State - Permite alterar o comportamento baseado no estado interno do objeto <<interface>> Estado +acao1() +ação2() Estado 1 +acao1() +acao2() Estado 2 +acao1() +acao2() Contexto +metodo() estado;
  • 25. public class Orcamento { private double valor; private List<Item> itens; public Orcamento(double valor) { this.valor = valor; this.itens = new ArrayList<Item>(); } public double getValor() { return valor; } public void desconta(double valor) { this.valor -= valor; } public List<Item> getItens() { return Collections.unmodifiableList(itens); } public void adicionaItem(Item item) { itens.add(item); } } public class Orcamento { public static final int EM_APROVACAO = 1; public static final int APROVADO = 2; public static final int REPROVADO = 3; public static final int FINALIZADO = 4; private double valor; private List<Item> itens; private int estadoAtual; // resto da classe escondida porque não cabia mais na tela public void aplicaDescontoExtra() { if(estadoAtual == EM_APROVACAO) valor = valor - (valor * 0.05); else if(estadoAtual == APROVADO) valor = valor - (valor * 0.02); else throw new RuntimeException("Orçamentos reprovados não recebem desconto extra!"); } }
  • 26. public class Orcamento { private double valor; private List<Item> itens; private EstadoAtualDeUmOrcamento estadoAtual; public Orcamento(double valor) { this.valor = valor; this.itens = new ArrayList<Item>(); this.estadoAtual = new EmAprovacao(); } // resto da classe porque não cabia mais na tela public void aplicaDescontoExtra() { estadoAtual.aplicaDescontoExtra(this); } } Em Aprovação Aprovado Reprovado Finalizado
  • 27. public class Orcamento { // resto da classe porque não cabia mais na tela public void alteraEstado(EstadoAtualDeUmOrcamento novoEstado) { this.estadoAtual = novoEstado; } public void aprova() { estadoAtual.aprova(this); } public void reprova() { estadoAtual.reprova(this); } public void finaliza() { estadoAtual.finaliza(this); } } public interface EstadoAtualDeUmOrcamento { void aplicaDescontoExtra(Orcamento orcamento); void aprova(Orcamento orcamento); void reprova(Orcamento orcamento); void finaliza(Orcamento orcamento); } public class EmAprovacao implements EstadoAtualDeUmOrcamento { @Override public void aplicaDescontoExtra(Orcamento orcamento) { orcamento.desconta(orcamento.getValor() * 0.05); } @Override public void aprova(Orcamento orcamento) { orcamento.alteraEstado(new Aprovado()); } @Override public void reprova(Orcamento orcamento) { orcamento.alteraEstado(new Reprovado());} @Override public void finaliza(Orcamento orcamento) { throw new IllegalStateException("Orçamentos em aprovação não podem ser finalizados"); } }