Padrão Repository, Dao e Factory

Pessoal,

Estou implementando um sistema e estou utilizando (da melhor forma que encontrei) esses três padrões na aplicação e gostaria da opinião de vocês. Já implementei os DAOs implementando as interfaces Repository, que são recuperadas por um Factory que criei. Minha dúvida está na entidade, como temos que deixar os nossas entidades mais inteligentes e com mais responsabilidades, adotei essa abordagem. Vejam o método encontrarPorId() e listarTudo() por exemplo, o que acham?:


/**
 *
 * @author Anderson
 */
@Entity
public class PerfilDeUsuario implements Serializable {
    
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;
    
    @Column(nullable=false)
    private String descricao;
    
    @Transient
    private IPerfilDeUsuarioRepositorio repositorio;
    
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getDescricao() {
        return descricao;
    }

    public void setDescricao(String descricao) {
        this.descricao = descricao;
    }
    
    public IPerfilDeUsuarioRepositorio getRepositorio() {
        
        if(this.repositorio == null){
            this.repositorio = FabricaDeRepositorios.getPerfilDeUsuarioRepositorio();
        }
        return this.repositorio;
    }
    
    public void salvar() throws Exception{
        this.getRepositorio().persistir(this);
    }
    
    public void excluir() throws Exception{
        this.getRepositorio().excluir(this);
    }
    
    public static PerfilDeUsuario encontrarPorId(Long id) throws Exception{
        return FabricaDeRepositorios.getPerfilDeUsuarioRepositorio().encontrarPorId(id);
    }
    
    public static List<PerfilDeUsuario> listarTudo(){
        return FabricaDeRepositorios.getPerfilDeUsuarioRepositorio().listarTudo();
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final PerfilDeUsuario other = (PerfilDeUsuario) obj;
        if (this.id != other.id && (this.id == null || !this.id.equals(other.id))) {
            return false;
        }
        return true;
    }

    @Override
    public int hashCode() {
        int hash = 3;
        hash = 97 * hash + (this.id != null ? this.id.hashCode() : 0);
        return hash;
    }
    
    
    
    
    
}

[code]# public static PerfilDeUsuario encontrarPorId(Long id) throws Exception{

return FabricaDeRepositorios.getPerfilDeUsuarioRepositorio().encontrarPorId(id);

}

public static List listarTudo(){

return FabricaDeRepositorios.getPerfilDeUsuarioRepositorio().listarTudo();

} [/code]

pq nao deixa esses metodos na FabricaDeRepositorios, deixa essa classe como abstract e faz a classe PerfilDeUsuario herdar dela? Ai esses metodos ficam implicitos pra todas classes que extends de FabricaDeRepositorios, sem precisar ficar reimplementando para todas as classes, todos os metodos que possuem em comum

Se for sistema web, eu usaria
Domain > Repository > Service > UI > tela

Domain, Repository: backend
Service > UI: frontend

mas ai nesse caso ficaria errado chamar de Fabrica… seria um DAOGenerico

Igor,

 A classe FabricaDeRepositorios só retorna instâncias de repositórios:

/**
 *
 * @author Anderson
 */
public class FabricaDeRepositorios {
    
    public static IPerfilDeUsuarioRepositorio getPerfilDeUsuarioRepositorio(){
        return new PerfilDeUsuarioDao();
    }
    
}

Igor,

 DaoGenerico no meu caso é uma classe concreta que utilizo pra extender DAOs através de herança pra reaproveitamento de código.  Estou utilizando a classe FabricaDeRepositorios nesse caso somente pra me retornar instancias de DAOs referenicados por Repositorys através de polimorfismo. Seria uma forma de não ter referências de DAOs diretamente nas minhas entidades, mas sim dos Repositorys, o que é a verdadeira intenção do pattern repository, já que ele é quem faz parte da camada de domínio e não o DAO. DaoGenerico seria somente pra reaproveitamento de código, ou seja, implementações.

Existem frentes que pregam o fato de tornar as entidades mais inteligentes, já outra acham que não o velho e bom POJO deve continuar do jeito que sempre foi.

Eu gosto da segunda alternativa.

mas acredito que se bem feito não haja tantos problema assim na primeira abordagem.

é que nesse caso que vc esta fazendo, vc misturou o Domain com o Repository… tah bem estranho isso…

Legal cara, obrigado pela dica. Um dos motivos pelo qual achei essa abordagem de entidades inteligentes interessante seria pelo fato dos controladores não precisarem conhecer os DAOS, incentivando o fraco acoplamento entre camadas, e acho que nesse caso o repositório seria como um “facade” para o subsistema de persistência, onde as entidades ficam totalmente livres da camada de persistência.