Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια

Dot Net Rules

Yes, to dance beneath the diamond sky with one hand waving free

Ιστορικό Δημοσιεύσεων

Explaining the Repository Pattern

In this post I will try to define the Repository Pattern, explain what it is and how we must use it in my ow words and according to my experience as a software engineer.

I will not be writing much code in this post but I will highlight the reasons why we need the Repository Pattern and what it helps us achieve.

Let me start with the official definition. Martin Fowle in his book Patterns of Enterprise Application Architecture (a must for every software engineer) gives the definition of the Repository Pattern: "Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.". You can read more link in his post.

In simpler words, the Repository Pattern creates an abstraction layer between the data access layer and the business logic layer of an application.

Repository design pattern is a way to simplify data access and enforce separation of concerns.

In every medium to large business application the Repository Pattern is necessary to bring seperation of concerns in our application as long as it is used correctly.

In the simplest words the repository pattern provides a clear separation between the application and the database access.

I think that most developers inherit a database before they start developing the application. They do not think in terms of the Domain Driven Design. They let the database shape the application code.They should think in a different way. The application domain, the business objects should be the heart of the application and shape the schema of the database. So we should not start building the application thinking about persistence for example.

Let me highlight the benefits of the Repository Pattern.

It helps us minimizes duplicate query logic.

I am pretty sure you have seen queries (Linq to Entities queries) inside a Controller. Well, never do that. Your code needs refactoring in that case.If not, you have a non testable application and an application that does not honor the seperation of concerns principle. It does not also honor the DRY (Do Not Repeat) yourself principle. It also vioates the theory of Clean Code Architecture.

Think like this. What is the MVC pattern? It is a UI pattern. A UI pattern is only, or should only be responsible for displaying data, data that is fetched to it by another layer. Controllers should not be responsible for querying. 

Querying is data access concern, it belongs to another class, to another layer, the repository layer or the data access layer.

By moving (refactoring your code) a method to a class called repository we can have many controlers use it, hence getting rid of duplicate query logic.

Let me give you an example. Let's say we need to design an asp.net (MVC 5.0) application, an e-shop, a book e-shop. Let's just imagine that we need to display in various parts of the application the 50 top available published books with most sales. We could have a query like this inside the controller

var BestSellerBooks = context.Books

.Where(b=>b.isPublished && b.isAvailable)

.OrderByDescending(b=>b.Sales)

.Take(50);
 

But what if we needed this data in many places inside the application? We should call the code above inside many controllers. That would be wrong and result in code duplication and in the end, in non maintenable code. 

Instead we could move the code in the repository class and the code inside our controller(s) could be

var BestSellerBooks = BookRepositor.GetBestSellerBooks(bookcategory, numofBooks)

The next great benefit of the repository pattern is the seperation of concerns. Well in general separation of concerns is a great thing. Most problems in applications is that we have database access code in all the areas of the application. Why does this happen?

A a controller receives a request and generates a response. The controller orchestrates everything. Builds a model and passes it to a view. That is all.

It should not access the database directly. It talks to the repository layer and says "Well give me the top selling authors or books or whatever".

Then the repository knows how to do that. It could use ADO.Net or EF or stored procedures to fetch the data. The domain layer or UI layer does not care about that and should not know about the implementaion details. Every layer has a concern so when testing or debugging our code we know which layer to look into.

Another benefit of the repository pattern is that it decouples your application from persistence frameworks.

Let's say that we use Entity Framework as the persistence framework. Then we decide for some reason to drop EF and use nHibernate. If we use the repository pattern correctly we could swap to nHibernate with minimal impact.

Even if I switch to nHibernate I will still call the 

var BestSellerBooks = BookRepositor.GetBestSellerBooks(bookcategory, numofBooks)

from the UI or Service layer. I do not care about the implementation details of how data is fetched.

Let's say that I have an ASP.Net MVC Core 1.0 application or an ASP.Net MVC 5.0 application that allows people to look for local doctors and book appointments on line.

The repository pattern in practice for the main domain/business object (Doctor)of this application should be something like this

public interface IDoctorRepository

{

Add(Doctor item)

Remove(Doctor item)

Doctor GetByID (int id)

IEnumerable<Doctor> GetAll()

IEnumerable<Doctor> Find(SomeCriteria, criteria)

}

This is the abstraction I need (the interface) to know only about business objects and not database objects.Τhese business objects are in memory collection objects. 

There are no methods like Update or Save. Save or persisting an object to the underlying data store is the business of another great pattern, the UnitOfWork Pattern.

Well, a lot of people, business people or junior developers still do not get the repository pattern. I will use a real life example to explain the repository pattern.

Let's think of employees who work for a known german car vendor/brand e.g Mercedes inside a car factory.

They work in a production line and they need a set of tools to finish decoration of the inside of a car.

They sit in the production line and press buttons. These buttons give instructions to a technical automated system that can fetch tools from a storage of tools within the factory.


After pressing a particular button that automated system fetches a tool to the employee who requested it. The employee finishes the work with that particular tool, presses a button, the automated system moves to a position where the employee places the specific tool, and the automated system stores it in a place where it knows how to fetch it from.

Does the employee know the inner workings of the automated system? No.

Does he need to understand how that automated system knows how to store and get tools to him? He does not. The employee is the "Business Domain Layer" of our application.

How does he communicate with the automated system? Through some abstraction, interface (buttons on a panel). The automated system is my repository layer/pattern, it abstracts from me (the employee-business layer) the inner workings of how tools are fetched.Hope it makes sense now.


To recap, the Repository Pattern abstracts the persistence layer, it is a collection of business objects in memory.

These business objects are stored and retrieved. One developer could use the EF to do that , another could use stored procedures to persist and retrieve those business objects.

The domain layer or the rest of the application does not know how these objects are persisted and the quite rightly so.

This is the job of the repository pattern and data access layer. The rest of the application communicates with repository layer/data access layer through well defined abstractions/interfaces.

Hope it helps!!!

Share
Posted: Κυριακή, 31 Ιουλίου 2016 1:47 πμ από το μέλος nikolaosk
Δημοσίευση στην κατηγορία: ,

Σχόλια:

Χωρίς Σχόλια

Έχει απενεργοποιηθεί η προσθήκη σχολίων από ανώνυμα μέλη