Design OO
-
Upload
mauricio-de-diana -
Category
Technology
-
view
780 -
download
3
description
Transcript of Design OO
Design OO
Mauricio De Diana
Atributos de qualidade
Manutenibilidade Robustez Reuso Legibilidade Testabilidade etc
Encapsulamento
"Esconder o estado interno de um objeto e fazer com que todas as interações com um objeto
sejam feitas através de métodos."
class Conta { private double saldo; // devia ser BigDecimal int getSaldo() { ... } // devia ser public void setSaldo(double novoSaldo) { ... }}
Conta c = new Conta();c.setSaldo(10.00); // inicializa conta double novo = c.getSaldo() + 5.00; // depósitoc.setSaldo(novo);
double novo = c.getSaldo() - 3.00; // saquec.setSaldo(novo);
Novo Requisito: CPMF (0,38% no saque)
Conta c = new Conta();c.setSaldo(10.00); // inicializa conta double novo = c.getSaldo() + 5.00; // depósitoc.setSaldo(novo);
double imp = 3.00 * 0.0038;double novo = c.getSaldo() - 3.00 - imp; // saquec.setSaldo(novo); // em mais 15 pontos do sistema... double imp = valor * 0.0038;double novo = c.getSaldo() - valor - imp; // saquec.setSaldo(novo);
// SEM CPMFclass Conta { private double saldo;
// Depois que o objeto é criado, // é impossível setar o saldo diretamente. Conta(double saldo) { this.saldo = saldo; } int getSaldo() { ... } void deposito(double valor) { saldo += valor; } void saque(double valor) { saldo -= valor; }}
Conta c = new Conta(10.00);c.deposito(5.00);c.saque(3.00);
class Conta { private double saldo;
Conta(double saldo) { this.saldo = saldo; } int getSaldo() { ... } void deposito(double valor) { saldo += valor; } void saque(double valor) { double imp = valor * 0.0038; saldo -= (valor + imp); }}
Conta c = new Conta(10.00);c.deposito(5.00);c.saque(3.00); // em mais 15 pontos do sistema... c.saque(valor);
Objetos consistentes
"O estado de um objeto deve ser sempre consistente."
class Cliente { private String cpf; private String endereco; private String cep;
String getCpf() { ... } void setCpf(String cpf) { ... } String getEndereco() { ... } void setEndereco(String endereco) { ... } String getCep() { ... } void setCep(String cep) { ... } }
Cliente c = new Cliente();c.getCpf().startsWith("1"); //NullPointerException
class Cliente { private String cpf; private String endereco; private String cep;
Cliente(String cpf, String endereco, String cep) { ... } String getCpf() { ... } void setCpf(String cpf) { ... } String getEndereco() { ... } void setEndereco(String endereco) { ... } String getCep() { ... } void setCep(String cep) { ... } }
Cliente c = new Cliente( "123456789-10", "R. X, 1", "12345-678");c.getCpf().startsWith("1");
Cliente c = new Cliente( "123456789-10", "R. X, 1", "12345-678");c.setEndereco("R. Y, 2");// faz outras coisas
class Cliente { private String cpf; private String endereco; private String cep;
Cliente(String cpf, String endereco, String cep) { ... } String getCpf() { ... } void setCpf(String cpf) { ... } String getEndereco() { ... } String getCep() { ... } void setEnderecoECep(String endereco, String cep) { ... } }
Cliente c = new Cliente( "123456789-10", "R. X, 1", "12345-678"); c.setEnderecoECep("R. Y, 2", "98765-432");
Entidades e Value Objects
"Muitos objetos não são definidos pelos valores de seus atributos, mas sim por uma linha de
identidade e continuidade"
"Muitos objetos não possuem identidade conceitual. Esses objetos descrevem características
de alguma coisa"
Cliente c = new Cliente( "123456789-10", "R. X, 1", "12345-678");c.setCpf("987654321-00");
class Cliente { private String cpf; private String endereco; private String cep;
Cliente(String cpf, String endereco, String cep) { ... } String getCpf() { ... } void setCpf() { ... } String getEndereco() { ... } String getCep() { ... } void setEnderecoECep(String endereco, String cep) { ... } }
class Cliente { private String cpf; private Endereco endereco; Cliente(String cpf, String endereco) { ... } String getCpf() { ... } String getEndereco() { ... } void setEndereco(Endereco endereco) { ... }} class Endereco { private String ruaENumero; private String cep; Endereco(String ruaENumero, String cep) { ... } // getters (sem setters)}
Endereco e = new Endereco("R. X, 1", "12345-678");Cliente c = new Cliente("12345678-9", e); Endereco novo = new Endereco("R. Y,2", "98765-432");c.setEndereco(novo);
Lei de Demeter
"Um método f de uma classe C só pode invocar métodos de:
CUm objeto criado por fUm objeto passado como argumento para fUm objeto em uma variável de instância de C"
class Funcionario { // devia usar generics private List tarefas = new ArrayList();
List getTarefas() { ... }}
Funcionario f = new Funcionario();f.getTarefas().add(new Tarefa("X"));f.getTarefas().add(new Tarefa("Y")); // remove primeiraf.getTarefas().remove(f.getTarefas().get(0));
class Funcionario { private List tarefas = new ArrayList();
void adicionaTarefa(Tarefa t) { tarefas.add(t); } void removePrimeiraTarefa() { tarefas.remove(tarefas.get(0)); }}
Funcionario f = new Funcionario();f.adicionaTarefa(new Tarefa("X"));f.adicionaTarefa(new Tarefa("Y")); // remove primeiraf.removePrimeiraTarefa();
class Cliente { private String cpf; private Endereco endereco; Cliente(String cpf, String endereco) { ... } String getCpf() { ... } String getEndereco() { ... } void setEndereco(Endereco endereco) { ... }} class Endereco { private String ruaENumero; private String cep; Endereco(String ruaENumero, String cep) { ... } // getters}
Endereco e = new Endereco("R. X, 1", "12345-678");Cliente c = new Cliente("12345678-9", end); c.getEndereco().getCep();
Endereco e = new Endereco("R. X, 1", "12345-678");Cliente c = new Cliente("12345678-9", end); c.endereco.cep;// não viola porque é acesso a ED
Princípios
Single Responsibility PrincipleOpen Closed Principle Liskov Substitution PrincipleInterface Segregation Principle Dependency Inversion Principle
(http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod)
SRP (Single Responsibility Principle)
"Não deve haver mais do que uma razão para uma classe ser alterada"
class Entrega { void setOrigem(Endereco endereco) { ... } void setDestino(Endereco endereco) { ... } void setMetodoEnvio(String metodo) { ... } Rota calcularRota() { ... } double calcularCustoEnvio() { ... } void imprimirEtiqueta() { ... }}
class Entrega { void setOrigem(Endereco endereco) { ... } void setDestino(Endereco endereco) { ... } void setMetodoEnvio(String metodo) { ... } Rota calcularRota() { ... }} class CalculoEnvio { double calcularCusto(Entrega entrega) { ... }} class ImpressaoEtiqueta { void imprimir(Entrega entrega) { ... }}
OCP (Open Closed Principle)
"Um módulo deve ser aberto para expansão efechado para modificação"
class Modem { void logon(TipoModem tipo) { if (tipo == TipoModem.Hayes) discaHayes(); else if (tipo == TipoModem.Courrier) discaCourrier(); else if (tipo == TipoModem.Ernie) discaErnie(); }
void discaHayes() { ... } void discaCourrier() { ... } void discaErnie() { ... }}
Modem m = new Modem();m.logon(TipoModem.HAYES);
class Modem { void logon(TipoModem tipo) { if (tipo == TipoModem.Hayes) discaHayes(); else if (tipo == TipoModem.Courrier) discaCourrier(); else if (tipo == TipoModem.Ernie) discaErnie(); else if (tipo == TipoModem.X) discaX(); }
void discaHayes() { ... } void discaCourrier() { ... } void discaErnie() { ... } void discaX() { ... }}
interface Modem { void disca();} class Hayes implements Modem { public void disca { ... }}
class Courrier implements Modem { public void disca { ... }} class Ernie implements Modem { public void disca { ... }} public void logon(Modem modem) { modem.disca();}
Modem m = new Hayes();m.logon();
LSP (Liskov Substitution Principle)
"Subclasses devem poder substituir suas superclasses"
class Retangulo { int larg; int alt; void setLarg(int larg) { this.larg = larg; } void setAlt(int alt) { this.alt = alt; } int getLarg() { return larg; } int getAlt() { return alt; } int area() { return larg * alt; }}
Retangulo r = new Retangulo();Cliente c = new Cliente();c.fazAlgo(r); class Cliente { void fazAlgo(Retangulo r) { r.setLarg(10); r.setAlt(20); assertEquals(10, r.getLarg()); assertEquals(20, r.getAlt()); }}
class Quadrado extends Retangulo { void setLarg(int larg) { this.larg = larg; this.alt = larg; }
void setAlt(int Alt) { this.alt = alt; this.larg = alt; }}
Retangulo r = new Quadrado();Cliente c = new Cliente();c.fazAlgo(r); class Cliente { void fazAlgo(Retangulo r) { r.setLarg(10); r.setAlt(20); assertEquals(10, r.getLarg()); assertEquals(20, r.getAlt()); }}
ISP (Interface Segregation Principle)
"Muitas interfaces específicas para clientes é melhor do que uma única
interface de propósito geral"
class Conta { void deposito(double valor) { ... } void saque(double valor) { ... } void investe(Investimento inv, double valor){...} void emprestimo(double valor) { ... }}
interface ContaCorrente { void deposito(double valor); void saque(double valor);} interface ContaInvestimento { void investe(Investimento inv, double valor);} interface ContaEmprestimo { void emprestimo(double valor);} class Conta implements ContaCorrente, ContaInvestimento, ContaEmprestimo { public void deposito(double valor) { ... } public void saque(double valor) { ... } public void investe(Investimento inv, double valor){...} public void emprestimo(double valor) { ... }}
ContaCorrente cc = new Conta();cc.deposito(10.00);cc.saque(5.00); cc.emprestimo(1.00);
DIP (Dependency Inversion Principle)
"Dependa de abstrações.Não dependa de coisas concretas"
class Cobranca { void calcula() { // faz varias coisas db.insere("TB_LOG", "Resultado: " + calc); } ...}
class Pedido { void criaPedido() { // faz varias coisas db.insere("TB_LOG", "Novo pedido: " + id); } ...}
interface Log { void escreve(mensagem);}
class DbLog implements Log { public void escreve(String mensagem) { db.insere("TB_LOG", mensagem); }}
class Cobranca { Log log; Calcula(Log log) { this.log = log; } void calcula() { // faz varias coisas log.escreve("Resultado: " + calc); } ...}
class Pedido { void criaPedido() { // faz varias coisas log.escreve("Novo pedido: " + id); } ...}
Log log = new DbLog(); Cobranca c = new Cobranca(log);
Finalizando
YAGNI (You Ain't Gonna Need It) Entender as razões por trás das regras "Pensar semanticamente, não sintaticamente"
"Accessors não são métodos"
Exceções: IoC JavaBeans Frameworks etc