Arquitetura para acesso ao banco - dao.save(pessoa) ou pessoa.save

Fala pessoal… blz?

Qual a opinião de vocês sobre estes dois modelos citados no título.

criar a camada de persistência separada (DAO) assim: dao.save(pessoa)
ou fazer com que o próprio bean saiba como executar esta regra (como Rails) pessoa.save?

da segunda maneira fica um código mais simples ao meu ver, porém será que para implementar desta maneira eu não perderia um pouco em performance, visto que este objeto teria que recuperar todas as informações sobre a persistência?

Vlw.

Para sistemas simples, códigos mais simples fazem mais sentido, certo? Então, seu sistema é simples? AR do Rails tem uma pequena diferença: os métodos só estão lá quando você precisa. Assim, do seu modo, o CRUD sempre estará dentro dos beanszinhos, faz mesmo alguma diferença deixar lá ou num DAO? Performance aí não difere não…

[quote=albiere]
criar a camada de persistência separada (DAO) assim: dao.save(pessoa)
ou fazer com que o próprio bean saiba como executar esta regra (como Rails) pessoa.save?[/quote]
A primeira opção remete ao pattern Data Mapper, já a segunda ao pattern Active Record. Em Java, AR é pouco usado pois é complicado implementar de forma elegante devido a estrutura da linguagem. Portanto, o mais comum é o Data Mapper (em Java é feito como DAO geralmente).

Na questão de performance, tanto faz.

Mas eu vejo algumas complicações para implementar o ActiveRecord (“pessoa.save()”). Este objeto precisaria de um DataSource ou de um EntityManager para realizar operações no banco. Usar singletons e statics costuma ser problemático, espalhar o objeto DataSource / EntityManager é ruim. O jeito é criar uma interface PessoaAbstractFactory, e uma classe PessoaFactoryImpl que, no seu método getInstance() develveria um objeto do tipo Pessoa já injetado. Bom, já que não deu pra entender, veja como fica na prática:


public class PessoaFactoryImpl implements PessoaAbstractFactory {
    
    private EntityManagerFactory emf;
    
    @Override // esse é o único método da interface
    public Pessoa newInstance() {
        // crio instância de pessoa injetando EntityManagerFactory
        Pessoa p = new Pessoa(emf);
        
        return p;
    }
    
    // método para injeção
    public void setEntityManagerFactory(EntityManagerFactory emf) {
        this.emf = emf;
    }
}

E é uma fábrica para cada entidade! Não é tão fácil fazer AR em Java quanto você pensa!

Como é mais comum a primeira opção (“dao.save(pessoa)”), iria nela.

Coincidência que andei pensando nessa questão ultimamente pra modelar um projeto.
Como o projeto é simples e as regras de persistência não vão mudar (não vou precisar trabalhar com SGBDs diferentes, etc.), decidi experimentar o Active Record. Mas pensei em fazer de forma que eu não tivesse que ter uma classe a mais por entidade.

Essa parte do acesso ao banco em si eu abstraí para uma superclasse comum à todas as entidades persistentes do modelo. Cada entidade que for persistida só precisa extender dessa classe e implementar os métodos abstratos persist, load, update e insert, que recebem uma conexão. Esses 4 métodos também tem assinaturas sem conexão na superclasse, que simplesmente criam a conexão e invocam o método correspondente nas subclasses.

É uma forma realmente simples de fazer persistência. Poucas classes e código limpo. Claro que não dá pra fazer com qualquer modelo, mas projetos de CRUD simples ficam beleza :smiley: