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?
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
É 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.
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.
[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.
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:
Posso considerar essa interface como respositório?
Como ficaria um repositorio então nesse meu caso?
Obrigado e acredito que todos estão tirando proveito desse tópico!
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…
[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;
}
Posso considerar essa interface como respositório?
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í:
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.
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: