0
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
     ...
class Conta {
  private double saldo;    // devia ser BigDecimal

    int getSaldo() { ... } // devia ser public
    void ...
Conta c = new Conta();
c.setSaldo(10.00); // inicializa conta

double novo = c.getSaldo() + 5.00; // depósito
c.setSaldo(n...
Novo Requisito: CPMF (0,38% no saque)
Conta c = new Conta();
c.setSaldo(10.00); // inicializa conta

double novo = c.getSaldo() + 5.00; // depósito
c.setSaldo(n...
// SEM CPMF
class Conta {
  private double saldo;

    // Depois que o objeto é criado,
    // é impossível setar o saldo ...
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() { ... }
    voi...
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() { ... }
    vo...
Cliente c = new Cliente();
c.getCpf().startsWith("1"); //NullPointerException
class Cliente {
  private String cpf;
  private String endereco;
  private String cep;

    Cliente(String cpf, String end...
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 ender...
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...
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 ender...
class Cliente {
  private String cpf;
  private Endereco endereco;

    Cliente(String cpf, String endereco) { ... }

    ...
Endereco e = new Endereco("R. X, 1", "12345-678");
Cliente c = new Cliente("12345678-9", e);

Endereco novo = new Endereco...
Lei de Demeter


"Um método f de uma classe C só pode invocar métodos de:
   C
   Um objeto criado por f
   Um objeto pass...
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 pr...
class Funcionario {
  private List tarefas = new ArrayList();

    void adicionaTarefa(Tarefa t) {
      tarefas.add(t);
 ...
Funcionario f = new Funcionario();
f.adicionaTarefa(new Tarefa("X"));
f.adicionaTarefa(new Tarefa("Y"));

// remove primei...
class Cliente {
  private String cpf;
  private Endereco endereco;

    Cliente(String cpf, String endereco) { ... }

    ...
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 vio...
Princípios

Single Responsibility Principle
Open Closed Principle
Liskov Substitution Principle
Interface Segregation Prin...
SRP (Single Responsibility Principle)



      "Não deve haver mais do que uma razão
           para uma classe ser altera...
class Entrega {
  void setOrigem(Endereco endereco) { ... }
  void setDestino(Endereco endereco) { ... }
  void setMetodoE...
class Entrega {
  void setOrigem(Endereco endereco) { ... }
  void setDestino(Endereco endereco) { ... }
  void setMetodoE...
OCP (Open Closed Principle)



    "Um módulo deve ser aberto para expansão e
           fechado para modificação"
class Modem {
  void logon(TipoModem tipo) {
    if (tipo == TipoModem.Hayes)
      discaHayes();
    else if (tipo == Tip...
Modem m = new Modem();
m.logon(TipoModem.HAYES);
class Modem {
  void logon(TipoModem tipo) {
    if (tipo == TipoModem.Hayes)
      discaHayes();
    else if (tipo == Tip...
interface Modem {
  void disca();
}

class Hayes implements Modem {
  public void disca { ... }
}

class Courrier implemen...
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...
Retangulo r = new Retangulo();
Cliente c = new Cliente();
c.fazAlgo(r);

class Cliente {
  void fazAlgo(Retangulo r) {
   ...
class Quadrado extends Retangulo {
  void setLarg(int larg) {
    this.larg = larg;
    this.alt = larg;
  }

    void set...
Retangulo r = new Quadrado();
Cliente c = new Cliente();
c.fazAlgo(r);

class Cliente {
  void fazAlgo(Retangulo r) {
    ...
ISP (Interface Segregation Principle)



         "Muitas interfaces específicas para
         clientes é melhor do que um...
class Conta {
  void deposito(double valor) { ... }
  void saque(double valor) { ... }
  void investe(Investimento inv, do...
interface ContaCorrente {
  void deposito(double valor);
  void saque(double valor);
}

interface ContaInvestimento {
  vo...
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);
  }
    ...
...
interface Log {
  void escreve(mensagem);
}


class DbLog implements Log {
  public void escreve(String mensagem) {
    db...
class Cobranca {
  Log log;

    Calcula(Log log) { this.log = log; }

    void calcula() {
       // faz varias coisas
  ...
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 sintatic...
Upcoming SlideShare
Loading in...5
×

Design OO

783

Published on

Apresentação feita para a equipe do IME-USP do projeto Groupware Workbench (http://code.google.com/p/groupware-workbench/).

Published in: Technology
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total Views
783
On Slideshare
0
From Embeds
0
Number of Embeds
0
Actions
Shares
0
Downloads
22
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Transcript of "Design OO"

  1. 1. Design OO Mauricio De Diana
  2. 2. Atributos de qualidade Manutenibilidade Robustez Reuso Legibilidade Testabilidade etc
  3. 3. 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."
  4. 4. class Conta { private double saldo; // devia ser BigDecimal int getSaldo() { ... } // devia ser public void setSaldo(double novoSaldo) { ... } }
  5. 5. Conta c = new Conta(); c.setSaldo(10.00); // inicializa conta double novo = c.getSaldo() + 5.00; // depósito c.setSaldo(novo); double novo = c.getSaldo() - 3.00; // saque c.setSaldo(novo);
  6. 6. Novo Requisito: CPMF (0,38% no saque)
  7. 7. Conta c = new Conta(); c.setSaldo(10.00); // inicializa conta double novo = c.getSaldo() + 5.00; // depósito c.setSaldo(novo); double imp = 3.00 * 0.0038; double novo = c.getSaldo() - 3.00 - imp; // saque c.setSaldo(novo); // em mais 15 pontos do sistema... double imp = valor * 0.0038; double novo = c.getSaldo() - valor - imp; // saque c.setSaldo(novo);
  8. 8. // SEM CPMF class 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; } }
  9. 9. Conta c = new Conta(10.00); c.deposito(5.00); c.saque(3.00);
  10. 10. 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); } }
  11. 11. Conta c = new Conta(10.00); c.deposito(5.00); c.saque(3.00); // em mais 15 pontos do sistema... c.saque(valor);
  12. 12. Objetos consistentes "O estado de um objeto deve ser sempre consistente."
  13. 13. 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) { ... } }
  14. 14. Cliente c = new Cliente(); c.getCpf().startsWith("1"); //NullPointerException
  15. 15. 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) { ... } }
  16. 16. Cliente c = new Cliente( "123456789-10", "R. X, 1", "12345-678"); c.getCpf().startsWith("1");
  17. 17. Cliente c = new Cliente( "123456789-10", "R. X, 1", "12345-678"); c.setEndereco("R. Y, 2"); // faz outras coisas
  18. 18. 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) { ... } }
  19. 19. Cliente c = new Cliente( "123456789-10", "R. X, 1", "12345-678"); c.setEnderecoECep("R. Y, 2", "98765-432");
  20. 20. 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"
  21. 21. Cliente c = new Cliente( "123456789-10", "R. X, 1", "12345-678"); c.setCpf("987654321-00");
  22. 22. 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) { ... } }
  23. 23. 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) }
  24. 24. 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);
  25. 25. Lei de Demeter "Um método f de uma classe C só pode invocar métodos de: C Um objeto criado por f Um objeto passado como argumento para f Um objeto em uma variável de instância de C"
  26. 26. class Funcionario { // devia usar generics private List tarefas = new ArrayList(); List getTarefas() { ... } }
  27. 27. Funcionario f = new Funcionario(); f.getTarefas().add(new Tarefa("X")); f.getTarefas().add(new Tarefa("Y")); // remove primeira f.getTarefas().remove(f.getTarefas().get(0));
  28. 28. class Funcionario { private List tarefas = new ArrayList(); void adicionaTarefa(Tarefa t) { tarefas.add(t); } void removePrimeiraTarefa() { tarefas.remove(tarefas.get(0)); } }
  29. 29. Funcionario f = new Funcionario(); f.adicionaTarefa(new Tarefa("X")); f.adicionaTarefa(new Tarefa("Y")); // remove primeira f.removePrimeiraTarefa();
  30. 30. 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 }
  31. 31. Endereco e = new Endereco("R. X, 1", "12345-678"); Cliente c = new Cliente("12345678-9", end); c.getEndereco().getCep();
  32. 32. 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
  33. 33. Princípios Single Responsibility Principle Open Closed Principle Liskov Substitution Principle Interface Segregation Principle Dependency Inversion Principle (http://butunclebob.com/ArticleS.UncleBob.PrinciplesOfOod)
  34. 34. SRP (Single Responsibility Principle) "Não deve haver mais do que uma razão para uma classe ser alterada"
  35. 35. class Entrega { void setOrigem(Endereco endereco) { ... } void setDestino(Endereco endereco) { ... } void setMetodoEnvio(String metodo) { ... } Rota calcularRota() { ... } double calcularCustoEnvio() { ... } void imprimirEtiqueta() { ... } }
  36. 36. 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) { ... } }
  37. 37. OCP (Open Closed Principle) "Um módulo deve ser aberto para expansão e fechado para modificação"
  38. 38. 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() { ... } }
  39. 39. Modem m = new Modem(); m.logon(TipoModem.HAYES);
  40. 40. 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() { ... } }
  41. 41. 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(); }
  42. 42. Modem m = new Hayes(); m.logon();
  43. 43. LSP (Liskov Substitution Principle) "Subclasses devem poder substituir suas superclasses"
  44. 44. 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; } }
  45. 45. 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()); } }
  46. 46. class Quadrado extends Retangulo { void setLarg(int larg) { this.larg = larg; this.alt = larg; } void setAlt(int Alt) { this.alt = alt; this.larg = alt; } }
  47. 47. 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()); } }
  48. 48. ISP (Interface Segregation Principle) "Muitas interfaces específicas para clientes é melhor do que uma única interface de propósito geral"
  49. 49. class Conta { void deposito(double valor) { ... } void saque(double valor) { ... } void investe(Investimento inv, double valor){...} void emprestimo(double valor) { ... } }
  50. 50. 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) { ... } }
  51. 51. ContaCorrente cc = new Conta(); cc.deposito(10.00); cc.saque(5.00); cc.emprestimo(1.00);
  52. 52. DIP (Dependency Inversion Principle) "Dependa de abstrações. Não dependa de coisas concretas"
  53. 53. 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); } ... }
  54. 54. interface Log { void escreve(mensagem); } class DbLog implements Log { public void escreve(String mensagem) { db.insere("TB_LOG", mensagem); } }
  55. 55. 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); } ... }
  56. 56. Log log = new DbLog(); Cobranca c = new Cobranca(log);
  57. 57. 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
  1. A particular slide catching your eye?

    Clipping is a handy way to collect important slides you want to go back to later.

×