Executando verificação de segurança...
4

Java Spring: Padrão DAO vs Repository

Padrões de projeto são soluções comuns e efetivas para problemas recorrentes no desenvolvimento de software. Alguns padrões, como o DAO e Repository, são importantes para separar responsabilidades e tornar o código mais manutenível e escalável.

Sobre o DAO e sua implementação

O padrão DAO separa as regras de acesso a banco de dados das regras de negócio em uma aplicação, isolando as operações em um objeto com uma interface definida.

public class Pessoa{
    private Long id;
    private String nome;
    private String cpf;

    // construtores, getters e setters
}
public class PessoaDao {

    private final EntityManager entityManager;

    public PessoaDao(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public void create(Pessoa pessoa) {
        entityManager.persist(pessoa);
    }

    public Pessoa read(Long id) {
        return entityManager.find(Pessoa.class, id);
    }

    public void update(Pessoa pessoa) {
        entityManger.merge(pessoa);
    }

    public void remove(Pessoa pessoa) {
        entityManger.remove(pessoa);
   }

}

Sobre o Repository e sua implementação

O padrão Repository também lida com dados, mas está mais próximo da lógica de negócios da aplicação. Ele fica entre as regras de negócio e a camada de persistência, fornecendo uma interface fácil de usar para acessar objetos de negócio e usando a camada de persistência para gravar e recuperar os dados.

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface PessoaRepository extends JpaRepository<Pessoa, Long> {
}

}
@Service
public class PessoaService {
    
    private final PessoaRepository pessoaRepository;
    
    public PessoaService(PessoaRepository pessoaRepository) {
        this.pessoaRepository = pessoaRepository;
    }
    
    public void criarPessoa(Pessoa pessoa) {
        pessoaRepository.save(pessoa);
    }
    
    public Pessoa buscarPessoaPorId(Long id) {
        return pessoaRepository.findById(id).orElse(null);
    }
    
    public void atualizarPessoa(Pessoa pessoa) {
        pessoaRepository.save(pessoa);
    }
    
    public void removerPessoa(Pessoa pessoa) {
        pessoaRepository.delete(pessoa);
    }
    
    // outros métodos do serviço...
}

Neste exemplo, estamos injetando o nosso PessoaRepository no construtor da classe PessoaService e utilizamos os métodos definidos na interface para buscar e salvar pessoas. Note que não precisamos implementar esses métodos manualmente, pois o Spring já gera a implementação automaticamente para nós.

Conclusão

O uso do padrão Repository é preferível ao uso do DAO com o Spring, porque ele incentiva um design orientado a domínio e permite uma compreensão mais fácil da estrutura de dados. Além disso, o Spring cria automaticamente a implementação dos métodos definidos no repositório, tornando o código mais simples e legível.

Carregando publicação patrocinada...
1

Vou aproveitar o artigo e trazer uma referência, que também faz parte do padrão DDD: https://martinfowler.com/eaaCatalog/repository.html

Acredito que é interessante reconhecer que, devido o largo número de exemplos com CRUD, temos uma inclinação a não saber como implementar o padrão Repository, o que acaba ferindo os conceitos de Domínio, Domain Services e Use Case. Utilizar classes anêmicas como entidade de domínio trás o malefício de uma refatoração custosa em aplicações de grande porte ou até mesmo em microservices pequenos. Entidades devem trazer consigo suas regras de negócio. Para o resto, não deveríamos nem ter testes unitários (só de integração mesmo) devido seu padrão de comportamento não passar da validação de modelo de dados. Para isso, o CRUD já deveria ser um problema resolvido. Acredito que é o que tentam fazer no Spring Data Rest.

1

Que ótima visão, Douglas. Acredito que seja importante considerar esses pontos e colocar eles em prática. Valeu por compartilhar o seu conhecimento, irei estudar mais sobre o assunto! :D

1

Por padrão, quando se estende de uma Repository predefinida não é necessário anotar com @Repository. Existe alguma convenção ou boa prática para essa anotação ou estou equivocado?

1

Então, neste caso específico, a anotação @Repository seria "redundante" e pode ser removida. Mas se você quiser manter a anotação por motivos de documentação ou organização do código, não há nenhum problema.

1

Fui apresentado primeiro ao DAO, e quando passei a usar o repository, continuei com uma camada de DAO, que nao deixa de ser um data access object, e deixava no service o que fosse parte lógica que fosse necessária, tipo converter entity em dto ou alguma validação antes de chamar a camada de acesso ao banco. É redundante usar um dao mesmo com repository? "Desobedece" alguma convenção?

1

Acredito que não seja redundante usar um DAO com um Repository, mas é importante entender que ambos desempenham funções semelhantes. Não existe uma convenção rígida que exija ou proíba o uso do DAO com o Repository, o importante mesmo é que a arquitetura do seu sistema faça sentido e seja fácil de entender e manter ;D