Padrões DAO e Repository
Tags: beginners, java, braziliandevs, todayisearched
Published: 2021-11-18 23:26:19

O **padrão DAO** (**Data Access Object** ou, em pt-BR, Objeto de Acesso a Dados), é uma abstração de persistência de dados e é considerado próximo da camada de armazenamento de dados que, normalmente, é centrado em tabelas.

Entretanto, em muitos casos, o DAO possui muitas tabelas permitindo, de uma forma mais direta, enviar/receber dados do banco, escondendo as queries mais feias.

Exemplo de implementação:

```java

//Primeiramente, criamos a classe de domínio
public class Usuario{
	private Long id;
	private String nome;
	private String email;

	//getters e setters
}

```

```java
//Na sequência, criamos uma interface que provê um CRUD simples para a classe de Domínio do Usuário
public interface UsuarioDao{
	void criar(Usuario usuario);
	Usuario buscar(Long id);
	void atualizar(Usuario usuario);
	void deletar(Long id);
}
```

```java
//Por fim, fazemos a implementação
public class UsuarioDaoImpl implements UsuarioDao{
	private final EntityManager em;

	@Override
	public void criar(Usuario usuario){
		em.persist(usuario);
	}

	@Override
	public Usuario buscar(Long id){
		return em.find(Usuario.class,id);
	}
	//...
}
```

##Padrão Repository

De acordo com Eric Evans em seu livro **Domain-Driven Design**, o "repository é um mecanismo para encapsular o banco, recuperar e buscar comportamento que simulam uma coleção de objetos."

Ainda nessa mesma linha, o livro **Padrão de Arquitetura de aplicações Enterprise**, do mesmo autor, diz que "entre as camadas de domínio e de mapeamento de dados, utiliza-se uma interface de coleção para acessar os objetos de domínio."

Em outras palavras, o repository também lida com dados e esconde queries de forma semelhante ao padrão DAO. Porém, o repository se trata de uma padrão de alto nível, ou seja, muito mais próximo da lógica de negócio de uma aplicação.

Consequentemente, um repository pode usar um DAO para pegar dados do banco e popular um objeto de domínio, da mesma forma que pode usar um DAO para pegar informações do objeto de domínio e mandar para o armazenamento no banco.

Exemplo de implementação:

```java
public interface UsuarioRepository{
	Usuario get(Long id);
	void adicionar(Usuario usuario);
	void atualizar(Usuario usuario);
	void remover(Usuario usuario);
}
```

```java
public class UsuarioRepositoryImpl implements UsuarioRepository{
	
	//Aqui vamos utilizar o DAO
	private UsuarioDaoImpl usuarioDaoImpl;
	
	@Override
	public Usuario get(Long id){
		return usuarioDaoImpl.buscar(id);
	}

	@Override
	public void adicionar(Usuario usuario){
		usuarioDaoImpl.criar(usuario);
	}

//...
}
```

Olhando da forma como fizemos até o momento, ambas implementações parecem muito semelhantes, porque a classe Usuario é uma classe de domínio anêmica. E, o repository, é somente outra camada sobre o DAO.

Entretanto, o DAO se torna um candidato perfeito para acesso aos dados enquanto que o Repository é uma forma ideal de se implementar um UseCase.

Um exemplo mais rico sobre o uso do Repository como UseCase:

```java
public class UsuarioRedeSocial extends Usuario{
	private List<Tweet> tweets;
}
```

```java
public class UsuarioRepositoryImpl implements UsuarioRepository{
	
	//Aqui vamos utilizar o DAO
	private UsuarioDaoImpl usuarioDaoImpl;
	//Pulamos a etapa de criar o Tweet e TweetDao, mas só para acelerar a compreensão de uma classe de Domínio mais rica
	private TweetDaoImpl
	
	@Override
	public Usuario get(Long id){
		//não queremos mais apenas salvar o usuário, mas queremos o usuário e seus tweets
		UsuarioRedeSocial usuario = (UsuarioRedeSocial)	usuarioDaoImpl.buscar(id);	
		List<Tweet> tweets = tweetDaoImpl.fetchTweets(usuario.getEmail());
        usuario.setTweets(tweets);

		return usuario;
	}

	@Override
	public void adicionar(Usuario usuario){
		usuarioDaoImpl.criar(usuario);
	}

//...
}
```

Nesse novo exemplo, temos agregação de informação que provê um objeto de domínio que é útil para o nosso UseCase. O poderíamos fazer o mesmo para as demais redes sociais, no mesmo Repository.

Fonte: [DAO vs Repository Pattern](https://www.baeldung.com/java-dao-vs-repository)