Dúvidas Repository

Minha aplicação está dessa forma…

Eu tenho a camada de aplicação onde onde ficam os services e o controller que comunica com Presentation Layer, construida em jsf. Quanto ao meu DOMAIN MODEL não encontrei dificuldade em entende-lo. As agregações, factoreis, os objetos de valor e vai,e os services do meu DO. Entrentanto minha dúvida está no Repositorio, eu vi algumas pessoas falando que eu não preciso ter uma interface para o repositorio visto que a ideia é nunca “trocar” implementação de repositorio, levando em conta que o repostiorio do dominio não é obrigado a ser implementado pelo DAO é ?

  • Disseram que o padrã DAO é usado para encapsular comandos SQL usado pela api de jdbc, ou caso eu queira comunicar minha app com outra aplicação ou legado, isso é correto?

+Se eu prentendo usar JDBC puro e não JPA por exemplo, eu posso não usar o DAO, por exemplo:

package minhaApp.Domain;

//Entidade
public class Cliente {

   private String cpf;
   private ClienteRepository clientes = new ClienteRepository();  //Aqui vou injetar via IoC logo mais..


   public void verificarSeJaEstaCadastado(String cpf) {
          if(!cpf==null){
             this.clientes.verificarSeJAEstaCadastrado(String cpf);        
          }
          else
              throw new exception("preecha cpf por favor..");
          }
   }

[code] //Repositorio…

package minhaApp.Domain

public Class ClienteRepository {

public void setDataSource(DataSource ds) {
… //pega conexao…via Spring…lebrando que vou usar JDBC puro…
}

public void verificarSeJAEstaCadastrado(String cpf) thows Exception {

   try {
         Connection cnn = ds.getConnection();
         String SQL = "SELECT c.cpf FROM cliente c WHERE c.cpf=?";
         Statement...
         ....
         ....
         if(cpf existe...).

           thow new exception("cpf existe..");

   }

}

}
[/code]

Ou seja, ao inves de criar uma interface repositorio para cada entidade, e depois implementar essa interface em uma classe
de infra-estrutura que poderia ser um DAO,…nao e melhor eu fazer tudo dentro do dominio mesmo usando JDBC?
olha só não vou usar um JPA/ Hibernate… visto que esses caras prá mim são um DAO,. eles tem os metodos add, list, remove…
então prá que criar redundancia…,? é logico que eu poderia usar JPA nesse projeto, e então eu teria meu entitiy manager dentro
da minha implementação de repositorio. porem nao quero usar ORM, não quero usar ORM…ja disse. como ficaria isso? tá certo?

Cara, é interessante usar os padrões de desenvolvimento. Com eles seu código ficará mais legível, organizado e muitas outras vantagens. Com o uso do DAO se mais pra frente vc quiser parar de usar JDBC e começar a usar JPA fica muito melhor e mais fácil de desacoplar seu código.

Por exemplo. Sua interface ClienteDAO:

public interface ClienteDAO{
  public Cliente find(Integer clienteId) throws DAOException;
  public void salva(Cliente cliente) throws DAOException;
}

sua implementação em JDBC:

public class ClienteDAOJDBCImpl implements ClienteDAO {

  public Cliente find(Integer clienteId) throws DAOException{
    // seu código jdbc
    // ...
  }

  public void salva(Cliente cliente) throws DAOException{
    // seu código jdbc
    // ...
  }

}

e agora o uso desta classe:

ClienteDAO dao = new ClienteDAOJDBCImpl();
Cliente cli = dao.find(cod);
dao.salva(cli);

Blz tá ótimo. MAAAS … e se vc não quiser mais usar JDBC ? Fácil …

public class ClienteDAOHibernateImpl implements ClienteDAO {

  public Cliente find(Integer clienteId) throws DAOException{
    // seu código usando hibernate
    // ...
  }

  public void salva(Cliente cliente) throws DAOException{
    // seu código usando hibernate
    // ...
  }

}

e na hora de usar veja q prático mude apenas a primeira linha:

ClienteDAO dao = new ClienteDAOHibernateImpl(); // Ao invés de ClienteDAOJDBCImpl()
Cliente cli = dao.find(cod);
dao.salva(cli);

pronto. não precisa mudar mais nada no seu código. Isso é um código muito mais bonito e de fácil manutenção.

Veja esta sugestão de arquitetura do blog da caelum:
http://blog.caelum.com.br/2010/07/26/possibilidades-de-design-no-uso-do-seu-generic-dao/

Você mencionou:

[quote]ao inves de criar uma interface repositorio para cada entidade, e depois implementar essa interface em uma classe
de infra-estrutura que poderia ser um DAO,…nao e melhor eu fazer tudo dentro do dominio mesmo usando JDBC? [/quote]

Não concordo, pois o domínio não deve ter nada de jdbc, domínio é domínio. O que acontece na realidade é colocarmos as anotações de JPA nas classes de domínio. OK, é uma adaptação do que prega o Domain Model e das práticas de arquitetura em camadas do Patterns of Enterprise Application Architecture do Fowler mas pelo menos você não acopla seu código de negócio com infra-estrutura, você apenas anota, sacou? Se for seguir à risca você teria que criar aqueles DTOs pra passar os dados de uma camada pra outra e tal.

sfidencio

uma coisa boa de deixar os SQLs juntos é que fica mais fácil modificar as coisas quando for necessário.

se vc for mapear tabelas que possuem muitas colunas, ou que possam mudar de nome durante o desenvolvimento, vc vai perceber rapidamente a desvantagem de usar JDBC.

usar JDBC hoje em dia, ao invés de ORM e afins, acaba sendo uma opção ruim para projetos grandes pq dificulta a manutenção e vc também perde produtividade. Mas nada aqui é lei. Às vezes, tudo o que vc quer é prototipar alguma coisa e às vezes com JDBC direto vc resolve logo e etc.

abraço

Léo

[quote=aluisiodsv]Cara, é interessante usar os padrões de desenvolvimento. Com eles seu código ficará mais legível, organizado e muitas outras vantagens. Com o uso do DAO se mais pra frente vc quiser parar de usar JDBC e começar a usar JPA fica muito melhor e mais fácil de desacoplar seu código.
[/quote]

Aluisio, eu sempre usei o padrão DAO visto que a função desse pattern é saber onde e como guardar, recuperar, tuplas em tabelas no sgbd e em seguinda mapea-las para objetos. Isso eu estou ciente.

Eu quero saber se poss seguir o padrão que o evans utiliza no exemplo dele. Ou seja, ele tem a entidade que esta associada
a interface repositoriy especifica, porem que implementa a especificação é a camada de infra-estrutura, no caso ele ta usando
hibernate, a pergunta é, posso substituir pelo jdbc sem precisar de DAO., dai eu chamo de ClienteRepositoryImp, dentro desse
cara ele tem a inteligencia de acesso a dados. O DAO seria usado se eu quisese abstrair o acesso a dados não? pelo menos foi o que entendi na proposta da SUN> http://java.sun.com/blueprints/corej2eepatterns/Patterns/DataAccessObject.html

Posso?

o exemplo extrai daqui…

http://dddsample.sourceforge.net/patterns-reference.html

Por exemplo. Sua interface ClienteDAO:

public interface ClienteDAO{
  public Cliente find(Integer clienteId) throws DAOException;
  public void salva(Cliente cliente) throws DAOException;
}

sua implementação em JDBC:

public class ClienteDAOJDBCImpl implements ClienteDAO {

  public Cliente find(Integer clienteId) throws DAOException{
    // seu código jdbc
    // ...
  }

  public void salva(Cliente cliente) throws DAOException{
    // seu código jdbc
    // ...
  }

}

e agora o uso desta classe:

ClienteDAO dao = new ClienteDAOJDBCImpl();
Cliente cli = dao.find(cod);
dao.salva(cli);

Blz tá ótimo. MAAAS … e se vc não quiser mais usar JDBC ? Fácil …

public class ClienteDAOHibernateImpl implements ClienteDAO {

  public Cliente find(Integer clienteId) throws DAOException{
    // seu código usando hibernate
    // ...
  }

  public void salva(Cliente cliente) throws DAOException{
    // seu código usando hibernate
    // ...
  }

}

e na hora de usar veja q prático mude apenas a primeira linha:

ClienteDAO dao = new ClienteDAOHibernateImpl(); // Ao invés de ClienteDAOJDBCImpl()
Cliente cli = dao.find(cod);
dao.salva(cli);

pronto. não precisa mudar mais nada no seu código. Isso é um código muito mais bonito e de fácil manutenção.