DAO's nas classes de negócio

Objetos de negócio que sabem o que significam DAOs quebram o princípio da inversão de dependências. DAO é algo concreto, ligado com a infra estrutura e não deve ser relacionado diretametne por um objetod e negócio.

Neste caso, use o padrão Repository. Note que um Repository pdoe ser apenas uma interface implementada por um DAO mas o importante é que um Repository é um conceito de negócios, um DAO não, por isso não liguem seus objetos de negócio aos DAOs.

DAO é uma coisa abstrata, não concreta. É uma interface que não é atrelada a nenhuma infra-estrutura.

Se eu tenho uma interface userDAO, ela pode ter qualquer tipo de implementação, inclusive TestUserDAO, DummyUserDAO, etc.

Se vc fala para o modelo de negócios não acessar o DAO, então ele acessaria o que? Acessar esse repositório, só estaríamos passando o problema do DAO para o repositório, não?

Ex do seu modelo de negócios:


private UserDAO userDAO;

public boolean edit(User u) {

    return userDAO.update(u) == 1;

}

Se o meu modelo de negócios não acessar o DAO acima ele vai acessar o que? Me interessei pelo que vc falou, mas estou com medo estarmos criando uma camada extra a troco de nada, o que seria um anti-pattern…

Um DAO não poderia ser considerado como um repositório de objetos e operações relacionadas a camada de persistencia? Vale a pena abstrair o DAO em mais uma camada chamada repositório?

De repente vale, não sei… O repositório é que se encarregaria de saber qual DAO usar e o Modelo usaria sempre o mesmo repositório… Não sei, ainda acho que uma interface userDAO tem exatamente essa função, ou seja, o modelo de negócios utiliza uma interface e essa interface que vai se virar para saber que implementação ela vai usar…

Eu acho q o saoj esta correto, imagina o tanto de classe que precisaria ser
criada pra fazer um simples crud…
poxa, jah temos uma interface UserDao, que abstrai o dao, entao criar mais
uma camada acho desnecessario minha opinião é

web -> action > model -> interface dao -> dao concreto -> banco

oque entendi estao querendo abstrair do model para o interface

web -> action > model -> repositorio > interface dao -> dao concreto -> banco

não vi finalidade apenas…

É uma questão de conceito. Se você tem uma interface dao para cada entidade do sistema (UserDao, ClienteDao, NotaFiscaDao) que não deixa pistas que tem um banco de dados embaixo dela e seus daos só fazem insert, update, delete e buscas (buscas previstas pela regra de negócio), vc na prática está trabalhando com repositórios. O que não é legal é passar a sessão do hibernate ou um dao genérico pro objeto de negócio.

Se você vai dar o nome de UserDao, UserStore ou UserRepository pra interface é só um detalhe.

[]'s

Rodrigo Auler

Exatamente, é ai que entra IoC (Inversion Of Control) para
injetar dentro do modelo o Dao.

ai sim o IoC funciona como um repositorio ± , porque ele que vai dizer qual
implementação de DAO que vc vai utilizar.

Antes que essa thread fique parecendo uma cacofonia em hospicio:

DAO: implementacao concreta do Repository. Nao deve ser usada por classes do dominio.

Repository: definicao da interace com o repositorio de dados (nao necessariamente uma interface, mas no maximo uma classe abstrata). Pode ser usada por classes do dominio, preferencialmente via injecao de dependencias.

Espero que fique mais facil se comunicar :slight_smile:

cv , agora não entendi mais nada, não consigo enchergar
isso na prática, e a verdadeira finalidade.

public interface ClientRepository {

   public ClientVO getClient(long id);

}

public class ClientDAO implements ClientRepository {

   ...

   public ClientVO getClient(long id) { ... }

}

public class ClientBOImpl implements ClientBO {

  public boolean aMethod() {
   ...
   this.clientRepository.getClient(id);
   ...
  }
}

A distribuição de classes seria mais ou menos isso ?

Sim, so que sem essa putaria de ClientBO, ClientVO e ClientBOImpl.

Leia: http://en.wikipedia.org/wiki/Test-driven_development

[quote=saoj]DAO é uma coisa abstrata, não concreta. É uma interface que não é atrelada a nenhuma infra-estrutura.
[/quote]

Não, Sérgio. DAO é algo que mapeia uma coisa apra outra, é um DataMapper. Ao pedir seus objetos para um DataMapper você está automaticamente sabendo que seus objetos na verdade estão em outro lugar.

Seja este lugar Oracle, hibernate, MySQL, XML ou Lucene isso é algo que não tem a ver com sua Camada de negócios. A Camada de Negócios modela negócios, ponto final, e existem poucos ramos onde o cliente lida com coisas como persistência.

Não, Repositório é um conceito de negócios, é basicamente uma lsita com métodos mais interessantes.

Você não está criando Camada alguma, você já criou (e está no título deste tópico): a camada de negócios. Repositório==negócios, DAO=persistência.

DAO abstrai apenas a lógica de persistência, não o fato de haver uma persistência, que deve ser abstraído da classe de negócios.

[quote=cv]Sim, so que sem essa putaria de ClientBO, ClientVO e ClientBOImpl.

Leia: http://en.wikipedia.org/wiki/Test-driven_development[/quote]

E

http://fragmental.com.br/wiki/index.php?title=Evitando_VOs_e_BOs

Não use VO/BO, use objetos

Ok, entendi.

Tenho o seguinte DAO que é acessado pelo modelo de negócios:

package org.mybooks.dao;

import java.util.*;

import org.mybooks.bean.*;

public interface UserDAO {
    
    public User loadById(int id) throws Exception;
    public int insert(User user) throws Exception;
    public void update(User user) throws Exception;
    public void delete(User user) throws Exception;
    public User loadByUsername(String username) throws Exception;
    public User loadByEmail(String email) throws Exception;
    public List searchUsersByName(List keywords, boolean and) throws Exception;
    public List searchUsersByName(List keywords, boolean and, int max) throws Exception;
}

Reparem algumas coisas:

:arrow: Ele é uma interface

:arrow: Ele não possui qualquer acoplamento a java.sql.Connection. org.hibernate.session, java.io.File, etc.

:arrow: Posso ter N implementações desse DAO, tais como, JdbcUserDAO, MySQLUserDAO (que extends JdbcUserDAO), HibernateUserDAO, LDAPUserDAO, TestUserDAO, DummyUserDAO, etc.

Algumas perguntas:

  1. Posso considerar essa interface como respositório?

  2. Como ficaria um repositorio então nesse meu caso?

Obrigado e acredito que todos estão tirando proveito desse tópico!

pqp
essas 3 páginas de tópico valem + a pena do que muito livro por aí :slight_smile:

Acredito que sim… O DAO implementa esse repository, e é utilizado algo para injetar a implementação.

É isso aí, saoj!

Daí, a implementação do repository pode ser obtida através de [i]dependency injection /i, service locator ou factories.

Ou seja, obtida por meio de padrões cuja finalidade é desacoplar ao máximo uma classe dependente (cliente) de uma implementação específica.

Eu chamei minha interface the UserDAO.

Por isso que eu falei que o modelo de negócios deve acessar o DAO. Na verdade ele vai acessar a INTERFACE UserDAO.

Resta saber se ao invés de chamar essa interface the UserDAO deveríamos chamar ela de UserRepository, ou ainda se isso deveria ser feito de outra maneira…

Eu também chamaria a interface de UserDAO e a implementação, de UserDAOBean, por causa das convenções de nomes da especificação EJB.

[quote=saoj] public interface UserDAO { public User loadById(int id) throws Exception; public int insert(User user) throws Exception; public void update(User user) throws Exception; public void delete(User user) throws Exception; public User loadByUsername(String username) throws Exception; public User loadByEmail(String email) throws Exception; public List searchUsersByName(List keywords, boolean and) throws Exception; public List searchUsersByName(List keywords, boolean and, int max) throws Exception; }

  1. Posso considerar essa interface como respositório?

  2. Como ficaria um repositorio então nesse meu caso?[/quote]
    Sérgio, eu mudaria um pouco o nome dos métodos para tirar os rastros que de que há um banco (ou algo do tipo). Trocando load/search por get, acho que já ficaria melhor. Trocando insert/delete por add/remove tb melhoraria um pouco.

Fica mais com cara de coleção, entende? Mas isso é só firula.

Fora isso, usaria unchecked exceptions para todos esses métodos e aí sim renomearia para UserRepository.

Sim, Sérgio, pode chamar de Repositório. Mas tem 2 coisas importantes aí:

  1. Nomes são muito importantes. Design Patterns são úteis entre outras coisas por definirem um nome comum a alguma técnicas, por isso nomenclatura deve ser usada com muito cuidado.

  2. Um Repositório não é um DAO, um DAO pode ser um repositório. Vou coalr aqui uma resposta minha na lsita de DDD que pode esclarecer:

http://tech.groups.yahoo.com/group/domaindrivendesign/message/5425

onde acho documentação da sun falando sobre esses padrões de nomes ?

e no caso, isso aqui estaria errado ?? Lá ele utiliza a nomeclatura DAO na interface…

Tá parecendo aquele velho papo que no mundo java existem vários nomes para a mesma coisa…