What’s the difference between DAO and Repository?

Asked

Viewed 26,848 times

64

What’s the difference between DAO and Repository?

Both are very similar, but in which case it is better to use one or the other?

I would like code examples.

  • 2

    From my experience in C#, the only difference is the nomenclature itself, both layers (Development Patterns) were responsible for the persistence of the data. DAO stands for (Data Access Object).

  • @Rod made a comment below that I think is relevant. I am formulating an answer on the subject to the question http://answall.com/q/101692/101 and I find the other answer much better, although I do not make the difference so clear. If I can think of something, I’ll give you an answer. I’m not saying I should do anything, just alert you. http://answall.com/questions/12927/qual-a-diff%C3%a7a-entre-dao-e-repository? Rq=1#comment211690_81151

  • After researching about I came to the conclusion that it is more semantic, conceptual. At most there are some rules of what can do or not in each one. Deep down, they serve the same purpose and work almost identically. So the answer Achilles Froes along with his clarifying comment is correct. What is certainly wrong is to talk about a business rule when the mechanism is only access to data. I will not say that the answer accepts being wrong, but it is confusing and does not exemplify well how they work.

4 answers

65


The goal is the same: Serve as abstraction to persist the data.

There is only one difference in its mode of use:

A repository is bound by the application’s business rule and is associated with the aggregation of your business objects and returns domain objects that represent this data.

Already o DAO (Data Access Object) at first has its scope limited in the capture and persistence of data from an DTO object (Data Transfer Object) representing a database record, consequently it transmits only the relational physical world of the database and does not represent the real business mini-world of your application.

Repository: Appraisal is business rule, encompasses everything on that rule, returning business domain objects

class AvaliacaoRepository
{
     public List<Aluno> AlunosAvaliados();
     public List<Gerente> GerentesAvaliados();
     public List<Avaliacao> TodasAvaliacoes();
     public List<Avaliacao> AvaliacoesEmAguardo();
}

DAO: Evaluation / User are Tables and its functions return objects (DTO) that represent the database records.

class AvaliacaoDAO 
{
     public List<DTOAvaliacao> TodasAvaliacoes();
     public List<DTOAvaliacao> AvaliacoesEmAguardo();
}

class UsuarioDAO 
{
     public List<DTOUsuario> AlunosAvaliados();
     public List<DTOUsuario> GerentesAvaliados();
}
  • 3

    Great approach, I didn’t know this difference in scope.

  • 7

    That is, DAO is dumb and Repository is smart. = D

  • In the Entity Framework, DAO would be the implementations of DbContext and the like? If it is, then I can say that these standards are not mutually exclusive, being possible to implement the repository standard, about the DAO standard... would that be?

  • @Miguelangelo, in fact the applicability of both models is valid only depending on the circumstance. This way it can be smarter for a given project to use a dumb approach and vice versa. I say this because a Repository (DDD) approach demands more abstraction and more work, being more recommended for larger projects with older resources :)

  • 2

    @Miguelangelo this, the EF is an ORM that advances much of the process of creation of DAOs and DTOs. This way it is quite acceptable that your Repository uses EF to persist and generate contextualized domain objects/aggregates.

  • 4

    Um... I already knew what DAO meant, but I had never attacked myself about what that pattern really was. This question, and this answer (+comments) were revealing to me. = D

  • 1

    Brief, well explained and in Portuguese. Perfeito!

  • 2

    Your response may be overly conscientious, causing some confusion for those who don’t have much background with the concept of entity aggregates, and you might want to go into it further. For example: how exactly is the repository "tied" to business rules? Another point: a Avaliacaorepository return objects other than Evaluations may even make sense in some context, but it is a bad example because the basic nature of a Type, as you said yourself, is to return aggregates from its root entity. That is: the most basic Repo only returns 1 type of entity.

  • 1

    @Caffé, its analysis is persistent, the report is linked to the "Evaluation" business rule and not obligatory to the Evaluation domain object, so everything associated with the Evaluation can be informed or returned by the repository, without you being forced to create N repositories for N domains that exist. The 1-1 Repositorio-Dominio model is widely used because of the ease of generics, but many domains may be associated with a business rule. (Student, Teacher, Classroom, College, etc -> Evaluation)

  • Your answer is correct as long as you do not add this last comment to it. Although I thought you were correct, some people found your answer confusing perhaps because you impressed on her, in a way that escaped me, this concept of your last comment, which is quite mistaken and mixing concepts.

  • 1

    @Caffé I will be more objective, instead of and put the methods scattered in each Repositorio (Teacher, Manager, Classroom, College), it is centralized those are in the Evaluation repository (Business Rule).

Show 6 more comments

48

Warning: I decided to risk an answer because I found the other confused or abstract, giving room to different interpretations about the patterns.

TL;DR

DAO and Repository are two standards of important projects, whose purposes have a small intersection area. However, as we will see below, they differ both in their objects, as in their origin and implementation.

Daos deal directly with the data source and abstract the operations performed on it. Repositories provide an interface to treat the storage and retrieval of domain entities as a collection.

DAO

A Data Access Object (Data Access Object) is an object that provides an interface abstracting a database or some other external persistence mechanism from the application.

Objectives:

  1. Encapsulation: Do not expose data source details to the rest of the application
  2. One-time responsibility principle: being the only place that works with SQL or specific dialect of that data source
  3. Meeting specific data source needs: properly mapping the application’s data structures or objects according to the specific data source types and structures

Example:

interface ClienteDao {
    void incluir(Cliente)
    void atualizar(Cliente)
    void atualizarUltimoAcesso(Integer,Date) //atualiza um campo
    Cliente recuperar(Integer)
    Cliente[] listarPorNome(String)
    ...
}

In summary, a DAO method follows the model:

umMetodoQualquerQueAbstraiUmaQueryEspecifica(ParametrosDaQuery)

Generally, each method of a DAO performs a single read or write operation in the database.

Repository

A Repository (Repository) is an object that isolates objects or entities of the domain of code that accesses the database.

We have that a repository implements part of the business rules regarding the composition of entities. It is strongly linked to the field of application and this is a direct reflection of the rules of business, because it abstracts storage and query of one or more domain entities.

However, we must not confuse this with business rules in the sense of information processing. A repository should not include business rules for making decisions, applying data transformation algorithms or providing services directly to other layers or modules of the application. Mapping domain entities and providing application functionality are separate responsibilities.

A repository is between the business rules and the persistence layer:

  1. It provides an interface to the business rules where objects are accessed as in a collection.
  2. It uses the persistence layer to record and recover the data needed to persist and recover the business objects.

So a repository can even make use of one or more Daos.

The interface of a repository is often analogous to the interface of List Java or C#, probably with the exception of search methods.

Example:

interface ClienteRepository {
    void persistir(Cliente)
    Cliente recuperar(Integer)
    List<Cliente> pesquisar(TermosDaPesquisa)
    List<Cliente> todos()
}

In the above example, in a simpler scenario, ClienteRepository.persistir() can make use of the method ClienteDao.incluir(). However, it can also check if the customer already exists and in this case use the method ClienteDao.atualizar(). Going further, if Cliente is a more complex domain entity it could load a list of addresses from another DAO.

Finally, repositories does not contain business rules, but contains logic to correctly build and persist the domain objects.

Frameworks ORM

Frameworks like Hibernate (Java) or Nhibernate (.NET) provide a much closer interface to the standard Repository because:

  1. Work with collections. See methods persist() and find().
  2. Searches are performed by an interface independent of the database type.
  3. They carry out the work of building and storing the application entities, including the possibility to automatically recover relation values, as in the example above on the client address list.

In addition, they also play the role of DAO because:

  • Store data directly in a database.
  • Generate the necessary SQL queries.
  • Map source data types to a suitable type in objects and vice versa.

On the other hand, it is clear that such frameworks can not always completely replace an application-specific repository because they are very generic. So even when using a ORM, it can be interesting not to mix your business rules with framework-specific code. In this case, creating Repositories that make use of the framework makes sense, as if it were a DAO++, after all you are at a higher level of abstraction and are not abstracting the access to the data source.

When to use the patterns

The use of Daos is practically a necessity if you do not use Orms, even if you use another nomenclature, after all you need a place to put SQL code.

Repositories, on the other hand, are interesting for slightly larger applications, where the cost of adding one more abstraction layer is justified by reuse in other components, modules and layers.

As described above, when working with an ORM, it makes sense to create repositories to abstract the framework-specific code. What doesn’t make much sense (I’ve seen it around) is to create Daos to abstract the ORM, because this is to force a little the concept of DAO.

Repositories are also quite useful for creating alternative implementations for storage. Because the interface is collections-based, it’s easy to implement a repository version using a list in memory, a very useful device for running unit tests or integration independently of the database.

Where they look like

The confusion starts because both DAO and Repository somehow abstract access to data, although, as we saw above, they have completely different levels of abstraction.

Another problem is that some of the operations (methods) of Daos and Repositories are common and, depending on the implementation, there is no difference. Part of this is the incorrect implementation of standards. Another part is because it is not always possible to follow the model in its completeness, for example when abstraction in the form of a collection penalizes performance in such a way that a repository needs to implement a lower-level method to make a functionality viable.

Where they diverge

A very important point to understand that the difference is not just accidental is to understand the origin of the patterns. While DAO was primarily designed to abstract generic data sources, the context in which Repository was designed involves DDD and can be used with other specific patterns. (source)

Daos can persist and recover Dtos or, in simpler systems, from the system’s own entities. Repositories always refer to an entity in the application domain. Of course you can extend the concept to other things, but it shouldn’t be the norm.

Daos usually abstract a query in the database. Repositories may need several queries to compose an entity.

Daos do not manage transactions. Repositories can manage or at least require execution within a transaction.

Daos directly access the data source. Repositories usually use some other mechanism to persist data, such as a ORM or Daos themselves.

  • thanks for your time and dedication for the reply, I will read and evaluate with the others, again, thank you!

  • Excellent answer! I want to add something: although they do not contain in themselves any business rules (there are controversies but in general this statement is not incorrect), the repositories are related to the business rule, because the repository knows the entities of the domain and their aggregations (as you described yourself), knowing their specific needs for persistence and recovery - especially bearing in mind the reference you quoted (Fowler), which in turn quotes the DDD. I will list some examples (1/3).

  • to) An entity that was once part of an aggregate gained more responsibility, identified for it a global identity and it became a root entity of its own aggregate. If you use repositories you will now need a new one to meet this change in business rules as you have a new root entity. b) If the way to recover entities with a certain state changes, you also need to change your repository. In these examples, we see that the Repository has changed due to changes in business rules (even without any changes in bank tables) (2/3)

  • 1

    Finally, I would say that Hibernate is much more for DAO than for Repository, since it does not know the specific needs and characteristics of a type of entity but rather the generic needs of ORM - not only of your domain but also of any other domain. In fact, if each repository specializes in one type of entity or aggregation, it would not make sense to have a generic interface for all repositories - I’ve had projects where some types of entities had and many others didn’t have a "findById", for example. (3/3)

  • @Caffé Thank you very much for the placements. I reviewed at least a couple of points of the answer. I believe the confusion occurred because sometimes we use the term "business rules" with different connotations. Of course, the domain is a reflection of business rules and, in this sense, repositories implement these rules..

  • @Caffé On the other hand I don’t think that the fact that repositories change due to domain changes is proof that they implement business rules. The entire application must be built on business rules. If we simply increment the size of a text field into a character there will be changes from the database to the on-screen validation Javascript. I just gave this example to show why I don’t usually include the domain or some restrictions in the "business rule", although I recognize that I need to employ another term to do this - I just don’t know what exactly

  • @Caffé When in Hibernate, I also updated the answer. It turns out that he fulfills the role of DAO and tries to play the role of a repository as much as possible. For the most common cases, you can map the business rules using annotations and named queries so that you get to something close to what you need, albeit using a generic interface. Of course in most serious applications this is not enough, so it is used as a DAO++.

  • 1

    You’re right, @utluiz, doesn’t really prove and great observation also about when Hibernate can be considered a repository. It is very difficult to express such complex concepts in comment or even in the answers here in the OS. It’s practically a miracle how much we can understand/learn/teach about these ideas in this format :-)

  • @Caffé. :)

Show 4 more comments

17

I’m sorry, but the Repository should not be associated with any business rule. Both the DAO and the Repository should be "dumb".

A Repository is the class responsible for all access to data of an Entity, actions such as include, edit, delete, and several queries are in the repository.

Other classes in a layer above the repositories are responsible for the business rules and consume the repositories to access the data.

Typically when used with interfaces the use of repositories dramatically speeds up the creation of the data access layer.

Here’s a simple example in C#:

Taking into account that you have a class that inherits from DbContext calling for SuaClasseDbContext (simplifying) this way:

public class SuaClasseDbContext : DbContext
{
   public DbSet<Autor> Autores {get; set;}
}

This interface says all entities must have a Id, which would be the primary key:

public class IEntidade
{
   public long Id; 
}

A generic repository, where the interface of a repository accepts any class that implements the interface IEntidade is defined with the basic methods:

public interface IRepositorio<T> where T: IEntidade
{
     void Adicionar(T entity);
     void Apagar(T entity);
     void Atualizar(T entity);
     void Salvar();
     T ObterPorId(int Id);
     IEnumerable<T> ObterTodos();
     IEnumerable<T> ObterPorFiltro(Expression<Func<T, bool>> filtro);
}

Next a class that represents an entity in your system, see that it implements the interface IEntidade:

public class Autor : IEntidade
{
    public int Id { get; set; }
    public string Nome { get; set; }
}

Then we can create the repository by implementing the defined interface:

public class AutorRepositorio : IRepositorio<Autor>
{
    private readonly SuaClasseDbContext dbContext;

    public AutorRepositorio(SuaClasseDbContext dbContext)
    {
        this.dbContext = dbContext;
    }
    
    public void Adicionar(Autor autor)
    {
        SuaClasseDbContext.Autores.Add(autor);
    }
    
    public void Apagar(Autor autor)
    {
        SuaClasseDbContext.Autores.Remove(autor);
    }
    
    public void Atualizar(Autor autor)
    {
            SuaClasseDbContext.Entry(autor).State = System.Data.Entity.EntityState.Modified;
    }

    public void Salvar()
    {
        SuaClasseDbContext.SaveChanges();
    }
    
    public Autor ObterPorId(int Id)
    {
        return SuaClasseDbContext.Autores.Find(Id);
    }
    
    public IEnumerable<Autor> ObterTodos()
    {
        return SuaClasseDbContext.Autores.ToList();
    }
    
    public IEnumerable<Autor> ObterPorFiltro(Expression<Func<Autor, bool>> filtro)
    {
        return SuaClasseDbContext.Autores.Where(filtro).ToList();
    }
}

When it’s time to use a Console Application, for example:

IRepositorio<Autor> repositorio = new AutorRepositorio();

// Regra de negócio responsável por consultar todos os autores que comecem
// com a letra A
// a regra de negócio está no consumo do repositório e não dentro dele
var resultado = repositorio.ObterPorFiltro(a => a.Nome.StartsWith("A"));
            
foreach (var autor in resultado)
{
   Console.WriteLine(autor.Nome);
 
}
  • 2

    -1 According to his answer there is no difference between the two patterns. But I change the vote at the same time to +1 explain the difference with some background.

  • I believe you can create an Insert in a Repository, which in fact will only persist given a condition is true. That’s business rule. So your definition of Repository is more pro DAO.

  • Hi utluiz, actually the concept of the two is the same, so there is no difference. However a concept can be implemented in several ways, so the Repositorio and the DAO differ, for usually a Repositorio is associated with the use of an ORM like the Entity Framework or Nhibernate (both for .net), and the DAO normally you manage the connection (opening and closing), worries about executing the SQL statement you wrote yourself, checks if it returned data, fills the collection, everything in hand.

  • 3

    +1 In fact the answer does not make clear the difference between the two, which is the focus of the question, but at least conceptualizes the thing correctly. This one may not have mentioned DAO, but the most voted not to go near what Repository is. But it does worse, she says it is. This is a classic case of wrong voting, probably because the bad answer was given before. to tell the truth the other answer just confused me.

3

Queries sql, jpaql, hql or whatever, are related yes to business rule, not directly and yes indirectly. So you can extract exactly the information you need from any repositório de dados, you need a pattern for this extraction to be done, in sgbds we use consultations sql.

Data access Objects are objects intended to abstract the way the information necessary for the execution of business rules is accessed, either through a sgbd, ldap, arquivo, filesystem etc. if we add query rules to these objects we will plaster them to just scan data that will obey that rule.

Repositories are responsible for manipulating this information already mined/extracted, either using the related languages above or another technique for the same purpose, it is clear that we will not have explicit business rules in these objects due to a better maintenance and or evolution (even if the implementation of the rule is query) for this reason our business objects will make use of these "data repositories" so that they can execute these rules.

A clear and practical example of this is the use of a relational object mapping that to facilitate the understanding we talk about the jpa/hibernate, where the classes responsible for containing the consultations jpaql/hql are not DAOS (taking into account the above definition), much less business objects but has the responsibility to contain the data we need to apply one or more rules.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.