How does the Repository standard work?

Asked

Viewed 3,003 times

28

I was doing a study on a framework in PHP called Symfony.

When I was studying about the database research, I realized that there are some differences in relation to the searches, as in frameworks as Cakephp 2 and Laravel 4.

Instead of using a model which by itself already makes the query, it just defines how to obtain and define the entity data.

Example:

class Usuario
{

     /**
     * @var integer
     *
     * @ORM\Column(name="nivel_id", type="integer")
     * @ORM\Id
     */
    private $nivelId;

    public function setNivelId($value)
    {}
}

There is no inheritance for another class, but only the class itself to represent the table data.

Then, when it comes to getting the data, instead of making calls like Usuario::findByNivel directly from the model, I see an entirely different encoding.

$usuarioRepo = $this->getDoctrine()
                     ->getRepository('AppBundle:Usuario');

// Depois de obter o repository, posso fazer as consultas no banco

$usuario = $usuarioRepo->find($id);

Then I realized that getRepository has something to do with the pattern repository.

  • How this pattern works?
  • What problem does he solve?
  • There’s a difference between this Pattern and the models used in other frameworks?

Observing: I’m not gonna put the tag PHP because it was only an example used through the language. Any answer about Repository is welcome ;)

1 answer

36


Definition

Roughly speaking we can say that it is a way of abstracting the persistence of data. It leaves the mechanism of how data is accessed isolated from business rules. It is not the entity and it is not the connection that makes the persistence, it is the repository, which is an independent class with the responsibilities uncoupling. Then access the data as a collection of any data, as if it were in memory, it doesn’t matter much how they are stored.

Perks

This allows not only to easily exchange the database, but all the logic of reading and writing data (log, cache, transaction and distribution coordination, authorization, etc.). Which is also great for facilitating the creation of formal tests, if well done.

Composition

Therefore it is very common, but not mandatory, that it be implemented through an interface or abstract class that establishes the basic contract of what can be done to persist the data.

It is common that he possesses the basic actions of all CRUD: add, delete, edit, get (to the Id), and list or find (to filter collection data). There may be variations of this and you can use other design patterns to make your use more flexible.

Example of the interface that creates this contract (in C#):

public interface IRepository<T> where T: IEntity {
    IEnumerable<T> List { get; }
    void Add(T entity);
    void Delete(T entity);
    void Update(T entity);
    T FindById(int Id);
}

I put in the Github for future reference.

Each entity in the repository will have to implement these methods as required.

The smarter the repository, the more it can help. The more he has knowledge of the persistence device and data structure, the more he can provide abstractions and process automations, freeing the programmer from doing a lot of manual stuff.

Problems he solves

When you let business rules take care of database queries (or other means of persistence) you spread them throughout the code, and changes in data structure, form of persistence, or other changes that affect queries in any way, require updating all code.

Note that it is common for business rules to specify the query itself, necessary for its use. Nothing wrong with that, which can not, according to this concept, is that the form the query is defined in the business rule. You cannot define how the mechanism will make the query. Speaking more clearly (even if it is a simplification), you cannot put SQL code in the business rule.

Where do we find him

You can create your own repository engine or you can use a done one. Many of these frameworks MVC, so famous today, has its own repository mechanism, or something like that. I believe that Ruby on Rails created the pattern of having these things together and due to its success what came after always copied the solution idea turnkey. It is very common for this pattern to work together with the ORM (looks like Hibernate started this). Maybe that’s why there’s some confusion of it with the model.

Its use is applied with the standard of dependency injection, as shown in the question example.

How it should be, and how it’s used

Let it be clear that it is not related to the business rule. Neither with the data nor with its behaviors.

Some like to implement repositories on top of a ready repository</sarcasmo>.

Some like to use it when you don’t need it. It is one more layer of abstraction, which is one of the most recurring problems in software development "modern".

All computation problems can be solved with an additional level of abstraction, except the problem of having too many levels of abstraction

-- there are contradictions who is the author

My experience shows that he doesn’t solve everything. To think that you can create an efficient and adequate universal application for any kind of persistence and scenario is, to say the least, foolish.

Of course the solution is good, just not perfect.

What I do know is that there is a lot of opinion about what is the right way to use this pattern. Which shows that it has problems. I am not criticizing him, just making it clear that there is no unanimity about him. And this must be taken into account before adopting him. Adopt carefully, making sure he is the solution and not a new problem.

There is controversy as to what should enter the specific repository of each entity. Some say it should be pure and only the generic basic operations typical of CRUD, as mentioned above, should be in the repository. Others think that specializations and any extra facilities of how to access the data can be added. One wonders how far this is no longer entering the field of business rule.

Abstraction of consultations

It is common to have a generic language to represent the consultations in business rules ensuring the abstraction of mechanisms. This is especially necessary when there may be mechanisms that do not follow the SQL relational database model.

Examples: LINQ or HQL.

In general they end up being limited by having to adopt the standard of the lowest common denominator.

Not always the translation home well and hide the concrete details can pass the wrong idea of the costs of its use.

When to adopt

Do you always need all this? No, often it’s too much.

It’s very easy to waste too much time and have less benefit.

One thing I always wonder before adopting something is whether it will save me work or increase what I have to do. You can’t always respond easily, especially without having experience with what you’re evaluating.

That’s why I say you need to know all the tools to know what to do.

When you only have one hammer, all the problems seem like nails

-- there are contradictions who is the author

Only they’re not. What’s there of people hammering screw around... And worse, they’re sure they’re doing the right thing.

People need to learn to automate software development more to not have stick.

OOP

There is the myth about object-oriented programming that it was the salvation of software development. It is far from true. It even brought some problems precisely because people have come to think that it is the definitive solution to everything.

There is no evidence, or even empirical evidence, that OOP is better than another paradigm. Of course it helps a lot in some scenarios, such as in GUI cases, some types of games, etc.

It already starts that often people talk a lot about OOP without really understanding what it is, its goals, how to use it properly. And it’s easy to understand why this happens.

There is no canonical definition of what OOP is. I myself do not fully understand what it is, so I do not defend it tooth and nail, as some do. I can’t defend what I’m not sure of. And it’s common for people to talk about using OOP when it’s not even true. Class is not synonymous with OOP, because they are not even necessary in this paradigm.

I tried to find an article by Joel Spolsky where he speaks of the "only three silver bullets of programming". If I remember correctly are:

  • High level languages - I think we can all agree that Assembly brought a fundamental change in how we program computers and a leap in productivity .
  • Automatic memory management - something so important that today there is practically no language mainstream that does not do this on its own or in the standard library, albeit partially. C is perhaps the only exception.
  • Modularization - There was a time when the applications were very small and it was easy to maintain them. As computational resources increased, more complex applications began to be developed. Even in the early days. But the human could not manage these complex code bases. Modularizing was the solution that allowed an explosion of complex applications.

Forget OOP, Agile, TDD, Patterns or other alleged silver bullets. All this helps but does not solve everything. None of this has made fundamental changes in the software development process. Fixation by certain technologies or methodologies may occur because of Dunning-Kruger effect.

Modularization

To modularization can be done in any paradigm. So it is possible to do procedural very well by adopting this practice. Of course, some languages do not facilitate this, but it is her fault and not the paradigm. In fact, procedural encourages modularization more than OO. The fact that some people do not understand, or follow this, is another problem.

Modularization is the basis of OOP, but many understand the opposite. There is a definition (among several) that says that object orientation is to approximate the behaviors of the states they will manipulate. Of course it makes some sense, but not the way people do it.

Why am I talking about OOP in this question?

Because the famous design patterns, like those of the Gang of Four came, in large part, to give a better understanding of the use of OOP. They came to show how to modularize the classes that were turning God Objects.

The Repository Pattern is one more pattern that solves the problem of people using OOP without knowing what to do. It promotes the separation of concepts, which is a fundamental principle that misused OOP has gone against.

It promotes the DRY, which I think is the most important principle of programming, and which most programmers can’t apply correctly - in fact I’ve never seen so much violation of this principle as it does today, and people can’t even perceive that it occurs.

It just tries to show the obvious, abstractions/generalizations are needed in complex systems, but it doesn’t show what should be obvious, that simple systems don’t need this.

Remember that although inheritance is a fundamental mechanism of OO, it should be avoided as much as possible because it is a coupling. Standards promote decoupling. What can be done in any paradigm. In some it is even natural, in OOP it is not. Welcome to the era of componentization, composition.

Completion

These bad uses of everything I’ve said here occur because people prefer shallow information. The lack of details causes the worst evil, the wrong use of the right thing. How many people click on links found and go deep into the information until they have everything they need?

Researching the subject I see more people making mistakes with this pattern than getting it right. But I don’t know, if it’s working, who am I to complain. It’s just complicated when it doesn’t solve and the person doesn’t understand.

  • 2

    You deserved it, man. Congratulations on the big (literally and allegorically) answer.

  • Congratulations @bigown was looking for exactly this.

Browser other questions tagged

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