Camada de Negócio e Camada de Persistência

Pessoal, estou com uma dúvida sobre a separação da camada de negócio da persistência. No meu exemplo estou usando uma classe bean qualquer, classe Pessoa por exemplo, e uma classe que gerencia classes Pessoa, uma PessoaManager, por exemplo, que salva uma Pessoa, que pesquisa pessoas por parâmetros, etc. Se eu usasse o NeoDatis ODB para persistir. A forma como ele persiste e faz a pesquisa é diferente de um SQL clássico. O Hibernate tbém utiliza uma forma diferente de pesquisar objetos, além de ter que fazer um mapeamento (XML) pra relacionar as classes e o banco de dados. Se fosse persistir em arquivo, seria uma forma diferente de pesquisar. Se minha classe que gerencia Pessoas utiliza SQL pra pesquisar e derrepente houvesse a necessidade de mudar pra Hibernate, vou ter alterar a forma de fazer a pesquisa na minha classe Manager. Ao meu ver separar em camadas é separar mesmo. Na minha opinião deveria ter uma linguagem universal para todos os tipos de persistência. Mudar a forma de persistir não deveria ser o mesmo que mudar o comando que a camada de negócio utiliza pra pesquisar.

O que vcs acham?

Para isso você poder usar o padrão (design pattern) DAO, com interfaces bem definidas que fazem essa separação transparente das coisas. Exemplo:

PessoaDAO (ou PessoaManager):

public interface PessoaDAO { public void salvar(Pessoa p); public Pessoa buscar(Long cpf); public List<Pessoa> buscarPorNome(String nome); }

PessoaHibernateDAO

[code]public interface PessoaDAO {
public void salvar(Pessoa p) {
// salva usando Hibernate
}

public Pessoa buscar(Long cpf) {
// busca usando Hibernate
}

public List<Pessoa> buscarPorNome(String nome) {
// busca usando Hibernate
}
}[/code]

PessoaJDBCDAO

[code]public interface PessoaDAO {
public void salvar(Pessoa p) {
// salva usando JDBC
}

public Pessoa buscar(Long cpf) {
// busca usando JDBC
}

public List<Pessoa> buscarPorNome(String nome) {
// busca usando JDBC
}
}[/code]

DAOFactory:

public class DAOFactory { public DAO getDAO(Class c) { // em algum arquivo de configuração busca a // implementação em uso e retornar a instância } }

Usando:

PessoaDAO dao = (PessoaDAO) DAOFactory.getDAO(PessoaDAO.class); pessoa = dao.buscar(12345678900); pessoa.setIdade(99); dao.salvar(pessoa);

Ai você teria um arquivo onde você diz qual a classe de implementação para aquele DAO.

PessoaDAO=PessoaHibernateDAO EmpresaDAO=EmpresaJDBCDAO ContratoDAO=ContratoHibernateDAO

A Factory encontraria a classe de implementação por meio desta configuração.

Você pode atá usar Spring no lugar deste Factory.

Ai seu programa não muda, pois ele usa uma interface comum para fazer as coisas.
Os comando que mudam são apenas na implementação da camada de persistência, o que não deveria interferir no resto do sistema.

Entendi, obrigado!

[quote=andre_guitar7]
O que vcs acham?[/quote]

Acho que vc tem toda a razão. Ao contrário do que se pode pensar o que vc escreveu não é resolvido pelo DAO.
O padrão que vc precisa usar é o DomainStore ( que é o que o JPA e o Hibernate usam). Ele é um Core JEE Pattern
só que o pessoal da sun só implementou para SQL. Com isto quero dizer que o JPA assume que vc vai escrever em tabelas e modelos relacionais ( por isso tem annotations como @Table)

Alguns padrões que são incluidos dentro do DomainStore
QueryObject : para escrever critérios
Interpreter : para passar dos objetos de critério para a API final
Strategy: para plugar diferentes esquemas de persistencia.
DataMapper : para mapear os objetos para os tipos da API final

Normalmente o DataMapper depende de algum esquema de configuração (xml, annotations…) de forma que vc possa escrever o mapeamento conforme o seu dominio e conforme a API final. Este é o coração da coisa.

Portanto, implemente um DomainStore que poderá resovler o seu problema

O que você quer fazer é algo muito simples e é exatamente o papel do DAO, mas se você tiver problemas ao gerar consultas específicas utilize QueryObject em conjunto.

Só cuidado com este PessoaManager, isso tá com cara de BO/VO. O que PessoaManager repreenta no domínio da sua aplicação?