Uma conversa sobre DAO e Orientação a Objetos

Pessoal ontem eu conversando com o meu chefe.

Eu em um projeto utilizei o padrão DAO. Mas ele condenou o padrão.
Usando mais ou menos a seguinte argumentação:

Que numa possivel classe Cliente os metodos de persistencia deveriam estar dentro dele:

[code]public class Cliente {

private String nome;
private int idade;

// gettets & setters

public void salvar(){}
public void select(){}
public void editar(){}
public void deletar(){}

}[/code]

E não numa classe separada como eu fiz

[code]public class Cliente {

private String nome;
private int idade;

// gettets & setters

}[/code]

[code]public interface DAO {

public int add(T t);
public T get(int id);
public boolean edit(T t);
public boolean delete(T t);
public List<T> getAll();

}[/code]

public class DAOCliente implements DAO<Cliente> { //implementacao }

Pois segundo ele a persistência de classes agregadas poderia ficar inviável.

PORÉM… eu sempre levo em conta que um projeto orientado a objetos deve ser COESO.
Eu acho que esse lance de persistencia dentro do bean fere totalmente isso… QUAL A OPINIÃO DE VOCES?

[quote=faeldix]…

Pois segundo ele a persistência de classes agregadas poderia ficar inviável…

[/quote]

Poderia explicar melhor o motivo do seu chefe pensar dessa forma? Com isso podemos argumentar em cima da linha de raciocínio dele.

Olá amigo.

A sua implementação está correta. Se a classe Cliente precisar ser utilizada em outra parte do projeto, as operações de inserção ao banco, por exemplo, ira junto?

Não sei qual o raciocínio do seu gestor, mas esse tipo de abstração proposta por você, eh algo intrínseco, ao meu vêr.

[]'s

O modelo mencionado pelo gestor dele é o padrão Active Record, descrito pelo Fowler no livro Patterns of Enterprise Application Architecture.

Se não me engano esse modelo é bastante usado com Ruby on Rails, e existem implementações Java também como o activejdbc.

Enfim, é um padrão, agora se um é certo e outro é errado, é difícil dizer.

[quote=CarlosEduardoDantas][quote=faeldix]…

Pois segundo ele a persistência de classes agregadas poderia ficar inviável…

[/quote]

Poderia explicar melhor o motivo do seu chefe pensar dessa forma? Com isso podemos argumentar em cima da linha de raciocínio dele.
[/quote]

O que ele quis dizer é que a persistencia das classe AGREGADAS a classe Cliente por exemplo.
Poderia ser facilitada. Pois geralmente as classes agregadas são tabelas no banco de dados.

Exemplo

[code]public class Cliente {
private Endereco endereco;

salvar()
deletar() /etc & etc

}[/code]

[code]public class Endereco {
String rua;
String bairro;

salvar()
deletar() /etc & etc

}[/code]

é uma abordagem interessante, provavelmente ele deve ter lido o livro do Eric Evans, de DDD e usado Active Record

pelo menos não há objetos anêmicos

[quote=Leozin]é uma abordagem interessante, provavelmente ele deve ter lido o livro do Eric Evans, de DDD e usado Active Record

pelo menos não há objetos anêmicos[/quote]

Pensando nesse aspecto, eh perfeito.

[]'s

[quote=faeldix]PORÉM… eu sempre levo em conta que um projeto orientado a objetos deve ser COESO.
Eu acho que esse lance de persistencia dentro do bean fere totalmente isso… QUAL A OPINIÃO DE VOCES?[/quote]

Porque você expôs os métodos de persistência. Faça assim…

[code]
public class Cliente {

private String nome;
private int idade;

// gettets & setters

public static Cliente[] loadClientes();

// domain methods no lugar de salvar, editar, deletar

}[/code]

minha opinião é que parece o padrão ActiveRecord.

é uma abordagem diferente =).

não melhor, nem pior… diferente.

eu ainda prefiro o DAO. hehe

Um post ótimo de 2007 no blog da caelum comenta sobre o assunto.

http://blog.caelum.com.br/repository-seu-modelo-mais-orientado-a-objeto/

[quote=douglaskd]minha opinião é que parece o padrão ActiveRecord.

é uma abordagem diferente =).

não melhor, nem pior… diferente.

eu ainda prefiro o DAO. hehe[/quote] Também prefiro a abordagem do DAO. :slight_smile:

Tem uma discussão interessante sobre isso em um post antigo. Vou procurar.

Na falta de uma, achei algumas interessantes que valem a pena:

Algumas pessoas tem certo preconceito em relação ao DAO. Dentre as várias razões, uma citada é o Active Record. Outra é o Repositório. Mas, na maior parte (pelo menos dos que eu conheço), é mimimi mesmo.

Em teoria, um Repositório é uma abstração de uma coleção de objetos, enquanto um DAO é uma abstração da persistência de objetos. Ou seja, DAO está mais próximo do banco enquanto o Repositório está mais próximo do domínio. Claro que você pode implementar um repositório usando DAO ou tendo um DAO por trás. Neste caso, a crítica que alguns fazem é que você não precisa criar o DAO pois ele já existe: o EntityManager do JPA, por exemplo. Daí você usa o Entity Manager para criar o Repositório. O Spring facilita muito esse trabalho com o Spring Data JPA. Dê uma olhada nele. É coisa linda de Deus (ou magia negra, na opinião de alguns)…

Como é muito comum em programação, tem gente que critica tecnologia/padrão/ferramenta X ou Y só porque ouviu alguém fazer isso. A criatura repete a crítica sem sequer pensar muito sobre o assunto, como se isso o tornasse mais competente. Como foi dito antes, DAO, Active record, Repositório… Tudo isso é Design Pattern, é ferramenta. Use-os quando necessário.

Na hora de desenhar uma arquitetura, leve em conta não apenas a opinião do seu chefe, mas coisas como desempenho, manutenibilidade, oferta de mão de obra apta a lidar com isso, treinamento, custo de absorção da tecnologia, suporte oferecido, restrições do cliente, etc, etc, etc…

Enfim, não dá pra escolher uma arquitetura baseado apenas em Acheologia. Até onde se sabe, essa ciência normalmente é fortemente acoplada à Autofuedologia.

Só para informação:

[quote=josenaldo]Algumas pessoas tem certo preconceito em relação ao DAO. Dentre as várias razões, uma citada é o Active Record. Outra é o Repositório. Mas, na maior parte (pelo menos dos que eu conheço), é mimimi mesmo.

Em teoria, um Repositório é uma abstração de uma coleção de objetos, enquanto um DAO é uma abstração da persistência de objetos. Ou seja, DAO está mais próximo do banco enquanto o Repositório está mais próximo do domínio. Claro que você pode implementar um repositório usando DAO ou tendo um DAO por trás. Neste caso, a crítica que alguns fazem é que você não precisa criar o DAO pois ele já existe: o EntityManager do JPA, por exemplo. Daí você usa o Entity Manager para criar o Repositório. O Spring facilita muito esse trabalho com o Spring Data JPA. Dê uma olhada nele. É coisa linda de Deus (ou magia negra, na opinião de alguns)…

Como é muito comum em programação, tem gente que critica tecnologia/padrão/ferramenta X ou Y só porque ouviu alguém fazer isso. A criatura repete a crítica sem sequer pensar muito sobre o assunto, como se isso o tornasse mais competente. Como foi dito antes, DAO, Active record, Repositório… Tudo isso é Design Pattern, é ferramenta. Use-os quando necessário.
[/quote]
Concordo, com uma unica ressalva: Como o amigo disse, são padrões a serem usados em situações que lhes cabem. DAO está cada vez menos necessário com as APIs atuais, mas Active Record (que é fazer com que a propria classe seja responsavel por “salvar-se”) em linguagens estáticas, fere o princípio da responsabilidade única. Qualquer classe tem, além da sua responsabilidade no negócio, a responsabilidade de conhecer detalhes de persistência e etc…

Nas linguagens dinâmicas tudo muda e o Active Record ganha muito a seu favor.

[quote=faeldix]
Pois segundo ele a persistência de classes agregadas poderia ficar inviável.

PORÉM… eu sempre levo em conta que um projeto orientado a objetos deve ser COESO.
Eu acho que esse lance de persistencia dentro do bean fere totalmente isso… QUAL A OPINIÃO DE VOCES?[/quote]

Eu achei estranho, mas funcionando… acho que tudo é válido.

perguntas…

o que acontece se a classe for dependente (tiver objetos agregados) de outra que também contenha métodos de persistência?
Como está a questão de desacoplamento e qual a visão dele sobre esse aspecto?

Mas olha só… Talvez isso não ajude muito porque alguns cadastros são compostos por mais de uma entidade. Os CRUDs destes cadastros, que apesar de terem algumas das mesmas entidades agregadas, podem ser feitos de formas diferentes (Um campo aqui e outro ali podem ser atualizáveis em um cadastro e não atualizavel em outro). Nesse caso, terá que escrever novamente seu método para o caso especifico. Onde ficaria esse método específico? Por isso que não se mistura VOs com BUs. Os Bus seriam a lógica de negocio do cadastro enquanto que os VOs são modelos de tabelas envolvidos na lógica.

O propósito do DAO é permitir o programador realizar o mapeamento do schema existente (legado ou recém criado por um analista) para código. Mas se você usa OO é o caminho inverso que você precisa fazer (criar o código e depois criar o banco) e geralmente faz pouco sentido pagar um programador pra quebrar cabeça com um problema resolvido há tempos e que pode ser automatizado por uma ferramenta ORM.

consultas você pode obter o gráfico de objetos completo ou usar algum tipo de lazy loading, ou uma combinação dos dois. Depende do que é mais apropriado pra sua aplicação.

nota: não sou o chefe dele mas tenho vasta experiência com OO.

pessoal desculpem minha ignorancia…

mas o que seria “objetos anemicos”?

[quote=faeldix]pessoal desculpem minha ignorancia…

mas o que seria “objetos anemicos”?[/quote]

http://www.arquiteturajava.com.br/livro/cuidado-com-o-modelo-anemico.pdf