SlideShare uma empresa Scribd logo
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"); }
}

Mais conteúdo relacionado

PDF
JavaScript - De verdade
PDF
PHP ao Extremo
PDF
A Classe StringBuilder em Java
ODP
Zend Framework - PHPSP - 2009
PDF
PHP Experience 2016 - [Palestra] Keynote: PHP-7
PPTX
Prática de laboratório utilizando views, stored procedures e triggers
PPTX
Stored Procedures and Triggers
PDF
Proxy, Man-In-The-Middle e testes
JavaScript - De verdade
PHP ao Extremo
A Classe StringBuilder em Java
Zend Framework - PHPSP - 2009
PHP Experience 2016 - [Palestra] Keynote: PHP-7
Prática de laboratório utilizando views, stored procedures e triggers
Stored Procedures and Triggers
Proxy, Man-In-The-Middle e testes

Mais procurados (20)

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

Semelhante a Design patterns (20)

DOCX
PDF
Combatendo code smells em aplicações Java
PDF
PDF
Refactoring
PPTX
ZeroBugsProject - Técnicas de programação efetivas
PPT
Introdução à análise orientada a objetos parte 1
PPT
Introdução à análise orientada a objetos parte 1
PPTX
If bom é if morto
PPTX
If bom é if morto
PPTX
Código Limpo
PPTX
Clean Code - Fork In Tuba
PPT
Introdução à análise orientada a objetos parte 2
PPTX
Clean Code
PDF
Aula 3 - Java Prof.ª Cristiane Fidelix
PDF
Android DevConference - SOLID no Android
ODP
Clean code
PPTX
Git, GitHub e OO
PPTX
Código limpo
PPTX
PPT
Combatendo code smells em aplicações Java
Refactoring
ZeroBugsProject - Técnicas de programação efetivas
Introdução à análise orientada a objetos parte 1
Introdução à análise orientada a objetos parte 1
If bom é if morto
If bom é if morto
Código Limpo
Clean Code - Fork In Tuba
Introdução à análise orientada a objetos parte 2
Clean Code
Aula 3 - Java Prof.ª Cristiane Fidelix
Android DevConference - SOLID no Android
Clean code
Git, GitHub e OO
Código limpo
Anúncio

Último (7)

PDF
Evolução em código: algoritmos genéticos com PHP
DOC
CODIGO PARA AUTOMATIZAR A JOGABILIDADE SUPER MARIO
PDF
apresentacao introducao computacao ead.pdf
PDF
Dos requisitos ao código: como criar código rastreável em PHP
DOC
COMO AUTOMATIZR JOGOS SUPER NINTENDO ATRAVES DA PROGRAMAÇÃO
PPTX
Mapeamento de Objeto para Tabela Relacional
PPTX
Curso de Windows 11 resumido na prática.pptx
Evolução em código: algoritmos genéticos com PHP
CODIGO PARA AUTOMATIZAR A JOGABILIDADE SUPER MARIO
apresentacao introducao computacao ead.pdf
Dos requisitos ao código: como criar código rastreável em PHP
COMO AUTOMATIZR JOGOS SUPER NINTENDO ATRAVES DA PROGRAMAÇÃO
Mapeamento de Objeto para Tabela Relacional
Curso de Windows 11 resumido na prática.pptx

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"); } }