O documento discute princípios de design orientado a objetos como encapsulamento, entidades e value objects, a lei de Demeter e princípios como responsabilidade única, aberto/fechado, substituição de Liskov e inversão de dependência. Ele apresenta exemplos de como aplicar esses princípios para melhorar a manutenibilidade, reuso e legibilidade do código.
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. class Conta {
private double saldo; // devia ser BigDecimal
int getSaldo() { ... } // devia ser public
void setSaldo(double novoSaldo) { ... }
}
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);
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. // 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. Conta c = new Conta(10.00);
c.deposito(5.00);
c.saque(3.00);
19. Cliente c = new Cliente(
"123456789-10", "R. X, 1", "12345-678");
c.setEnderecoECep("R. Y, 2", "98765-432");
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. Cliente c = new Cliente(
"123456789-10", "R. X, 1", "12345-678");
c.setCpf("987654321-00");
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. 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. class Funcionario {
// devia usar generics
private List tarefas = new ArrayList();
List getTarefas() { ... }
}
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. class Funcionario {
private List tarefas = new ArrayList();
void adicionaTarefa(Tarefa t) {
tarefas.add(t);
}
void removePrimeiraTarefa() {
tarefas.remove(tarefas.get(0));
}
}
29. Funcionario f = new Funcionario();
f.adicionaTarefa(new Tarefa("X"));
f.adicionaTarefa(new Tarefa("Y"));
// remove primeira
f.removePrimeiraTarefa();
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. Log log = new DbLog();
Cobranca c = new Cobranca(log);
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