Friday, November 2, 2018

REPOSITORIES | Infrastructure Layer | Domain Driven Design

What are Repositories in Domain Driven Design




Repository: Repositories save and retrieve Entities or Aggregates to or from the underlying storage mechanism. Repositories are part of the domain model, so they should be database vendor independent. Repositories can use DAOs(Data Access Objects) for retrieving data and to encapsulate database specific logic from the domain. Note: Hibernate is also a Data Access Object! Wrapping Hibernate inside a DAO can be an overkill. Repositories can use an Aggregate Oriented Database.



  • Decouple the domain layer from database strategies and infrastructure code.
  • Provide the retrieval and persistence needs of aggregate roots.
  • The repository is a contract, not a data access layer.
  • The repository is for transnational behavior, not for ad hoc reporting.
  • A repository should be scoped to updating a single aggregate; it should not control a transaction. This should be the responsibility of a unit of work.

Repository

Repository is a memory segment that is used to safely store all the necessary elements. This is what a domain-specific repository actually is. Repositories are used to store aggregates. When aggregate is placed into a specific repository and then get extracted from it, you get a unified object. If aggregate is modified, all the modifications will be saved. If aggregate is deleted, you will no longer be able to extract it.
Every aggregate that needs to be stored for a given time period should have its own repository.
Often, repositories are designed to guarantee that all previously generated aggregates can be easily found in it. Therefore, there are two types of repositories:
  1. Repositories that imitate collections;
  2. Repositories that store data permanently.
Repositories that imitate collections are good at imitating collections, modeling at least a part of its interface. Its interface doesn’t show the permanent storage mechanism in any way possible and is used as a standard DDD pattern.
You can view this repository as HashSet<ObjectId, Object>. In this collection, you can’t insert similar elements twice. When the object is received and modified, all the changes are saved and applied right away.
Though the clients shouldn’t deal with the permanent storage mechanism, you need to constantly pay attention to how this mechanism operates and how it stores all the changes in objects. To do this, you can:
  1. Rely on implicity copy-on-read method (The permanent storage mechanism copies stored objects every time the database is requested and then compares the closed copy with the client one whenever a transaction is underway)
  2. Use implicity copy-on-save method (The mechanism manages uploaded objects using proxy objects).
Such mechanism as Hibernate allows you to create any type of repository, which is specifically designed to imitate the collection.
Under the high-performance conditions, it is costly to store all the objects in the memory. It overloads the memory and its system too much. But in case of repository that utilizes the permanent storage mechanism, you shouldn’t focus too much on how and when the objects are modified; you should just save all the changes with save() method. Like this:
To implement and use repository, rely on multiple methods and objects of the permanent storage mechanism. It is important that repository is created on the infrastructure level but the interface is declared in the domain.
In this case, you need to use the first repository type (the one that I used to imitate collections). It can be used with save() and put(). Only the collection methods.
Access to the database and other mechanisms get encapsulated in repository. The client side will be rather simple and won’t depend on methods used to create the repository itself.

Repositories

In DDD approach they form an intermediate layer between our domain modeling and the persistence of its states in the database. Saving and recovering the state at every moment through abstractions responsible for providing the necessary methods of communication with the persistence infrastructure.
Infrastructure layer will be in charge of hosting the necessary implementations according to the technologies or mechanisms (SQL, Redis, MongoDB, In-Memory, ORM) of persistence that we can and are interested in having. Through mechanisms that facilitate DI, we will use the one that suits us in each context .
There are two types of repository design more usual, oriented to collections and oriented to persistence: Collection-oriented respositories and persistence repository.
Collection-oriented respositories is considered the main design of repositories focused on DDD . Using instances in memory as the main use until the commit in which the state of the entity or aggregate willpersistthrough abstractions of the repositories to carry out the necessary action according to the state of the element in memory vs. persisted.
To avoid the problems that may arise from the concurrence of users in the writing, there are strategies of versioning in persistence, increasing it in each modification and later checking in subsequent writings to carry out the necessary action in each moment.
Persistence repository is related and oriented to the traditional CRUD methods, by transacting each state writing action on the database. Approach with great influence on the use of DAO .
It is considered a bad practice in DDD to inject any type of service or repository in the domain model. You must inject them into the application services to orchestrate the persistence and state construction of each element of our domain model.

What are the benefits of using Repositories?
So far in this series of blog posts we’ve looked at building and working with Repositories a couple of times.

A Repository is basically a layer that sits between your project’s domain and the database.

Whilst I think The Repository Pattern is becoming pretty well known, it seems to me that there is still confusion over why exactly you would use it, and what the real benefits of it are.

In today’s tutorial I’m going to be looking once again at The Repository Pattern to uncover the real beauty of the design.

Round up of previous examples
Before I jump into the exploration of The Repository Pattern, first we should look back at the two previous posts in this series that also mention the use of Repositories.

The first mention of Repositories was in the post Creating flexible Controllers in Laravel 4 using Repositories. This was the first tutorial that mentioned using a Repository as a layer between your controller and your database. By injecting an instance of an object that implements an interface, we can very easily switch out objects that also implement the same interface.

The next mention of using Repositories was in the post Eloquent tricks for better Repositories. In this post I looked at how you can create an abstract Repository to allow you to reuse common database querying methods. Many of the foundational aspects of a Repository will be consistent from implementation to implementation and so it makes sense to write reusable code.

What are Repositories?
So if you’ve already read those previous posts I’m guessing you are probably already have a fair idea of what a Repository is used for.

But do you understand the real reasons behind using a Repository in the first place? Whilst on the surface the reasoning behind The Repository Pattern seems pretty obvious, I think many people overlook the nuances.

I think there are basically four main benefits of using The Repository Pattern in an application.

Data storage as a detail of the application
The first big benefit of using The Repository Pattern is it moves you closer to thinking about the database as merely a detail of the overall application.

A lot of applications get their first burst of growth through the design of the database schema. Whilst many CRUD-centric applications are very much database oriented, this is the wrong approach for an entirely different suite of applications.

The database is a detail of your application. You should not design your application around how you intend to store the data.

The benefit of using The Repository Pattern in this instance is that you can write the Repository interface at the beginning of the project without really thinking about the actual technical details of how you are going to store your data.

For example, you might have the following UserRepository interface:

interface UserRepository {

public function findUserById($id);

public function findUserByUsername($username);

public function add(User $user);

public function remove($id);  
}  
Instead of bothering to set up the database, you can instead write an in memory implementation that simply stores the data in a really lightweight way:

class InMemoryUserRepository implements UserRepository {

/** @var */  
private $users;

public function findUserById($id)  
{  
return $this->users[$id];  
}

public function findUserByUsername($username)  
{  
return array_filter($this->users, function ($user) use ($username) {  
return $this->user->username === $username;  
});  
}

public function add(User $user)  
{  
$this->users[$user->id] = $user;  
}

public function remove($id)  
{  
unset($this->users[$id]);  
}  
}  
You can then continue to build out the real important bits of your application knowing that whenever you get to the point of really needing to store data, you can simply write a Repository implementation that satisfies the requirements of your Repository interface.

Much easier for testing
The second great reason, very much related to the first reason, for using The Repository Pattern is because it make testing your code a lot easier.

Whenever you need to add or query data from the database in your application, instead of hard coding that dependency, you can inject an instance of an object that satisfies the requirements of your Repository interface.

For example, you wouldn’t want to write the following code in your application:

public function find($id)  
{  
$repository = new EloquentUserRepository;

return $repository->findUserById($id);  
}  
By creating a new instance of EloquentUserRepository directly in the method you’ve coupled that dependency to your code.

Instead you should inject an object that meets the requirements of an interface:

public function __construct(UserRepository $repository)  
{  
$this->repository = $repository;  
}

public function find($id)  
{  
return $this->repository->findUserById($id)  
}  
By injecting an object that satisfies an interface we can very easily inject a different implementation during testing that does not require the test to hit the database:

public function test_find_user()  
{  
$repository = new InMemoryUserRepository;  
$controller = new UserController($repository);

$user = $controller->findUserById(1);

$this->assertInstanceOf(‘User’, $user);  
}  
A one-way dependency
Good applications are comprised of a number of different layers that each have a single responsibility within the software stack.

The very top layer is the User Interface. The User Interface is used for displaying data to the user, accepting user input and sending it that input back into the application.

Next we have the HTTP layer that accepts the user input and directs where requests should be sent.

Next we have the application layer that co-ordinates what services we need in order to satisfy the page request.

Next we have the domain layer where the real business logic of the application sits.

And finally at the very bottom we have the database. The database is essentially on the other side of a wall under the domain layer because it’s not really our responsibility.

So as you can see, an application is comprised of a number of different layers. Each of these layers have a single responsibility within the application.

Each layer is also essentially oblivious to the layers below. The User Interface does not care whether the application is written in PHP, Ruby or Java. As long as the HTTP layer can send and receive requests, that’s all that meters.

The HTTP layer does not care about what the Application layer does to satisfy the request. It only cares about sending an appropriate response.

The Application does not care how the Domain layer decides what is considered accepted and what is considered against the business rules, the Application layer has no knowledge of “business rules”.

The Domain layer does not care about how the data is actually stored on the other side of the wall, it only cares about sending and receiving data to satisfy the requests from above.

So as you can see, each layer is totally oblivious to the layers below.

By using The Repository Pattern it allows us to create a one-way dependency between the domain and the data mapping layers.

The in-memory illusion
If we look at the definition of a Repository from the book Patterns of Enterprise Application Architecture we will find the following quote:

Mediates between the domain and data mapping layers using a collection-like interface for accessing domain objects.

One of the most important characteristics of The Repository Pattern is the fact that it provides a “collection-like” interface.

This means that you should think of accessing the data in your database in the same way you would working with a standard collection object.

The fact that we use databases in applications is really because we need some way of storing the data in a persistence storage, and so it makes sense to use a database.

We should therefore think of the data as if it is stored in a collection, rather than letting the terminology of the database creep into our application.

This means instead of having methods such as save(User $user) we should use add(User $user).

Why is this important? Well at the end of the day we’re still going to be using databases for a long time yet. The fact remains though, that the database should not dictate the design or implementation of your application.

By modelling the interaction with the database as behind the curtain of a collection-like interface we move further away from the database-centric application design that has held us back for so long.

Writing the first repository
A couple of weeks ago we looked at The Specification Pattern.

The Specification Pattern is a way of encapsulating business rules around the selection of objects within an application. In order to “select” those objects, we need a way of querying the database.

In that previous tutorial we injected an interface of UserRepository into the Specification Object.

This is a good example of not allowing the database to hold up progress of the really important bits of the application. We can simply inject an instance of the interface and worry about the database later.

Today we will look at the first tentative steps at writing the UserRepository interface.

Create a new file under Cribbb\Domain\Model\Identity called UserRepository.php:

<?php namespace Cribbb\Domain\Model\Identity;

interface UserRepository {}  
Note: I’ve renamed the Users namespace to Identity so the purpose of the code is more explicit. All the code from the last couple of weeks is still there.

The first two methods I will add will be used to find a user by their email address or username. These two methods were required by the Specification object:

/**  
* Find a user by their email address  
*  
* @param Email $email  
* @return User  
*/  
public function userOfEmail(Email $email);

/**  
* Find a user by their username  
*  
* @param Username $username  
* @return User  
*/  
public function userOfUsername(Username $username);  
The next method I will create will be for adding a new user to the application. I’m going to need this method when I write the code to register a new user.

As I mentioned above, we should think about the Repository as if it were an in-memory collection, rather than a gateway to a database:

/**  
* Add a new User  
*  
* @param User $user  
* @return void  
*/  
public function add(User $user);  
As you can see I’m requiring that an instance of User is passed in. The Repository is responsible for storing and retrieving objects. The Repository is not responsible for taking a raw array of data attributes from the request and creating the User object internally.

And finally I will add a method to return the next identity to use. If you remember back to last week you will know that instead of using auto-incrementing id’s I’m going to be using UUIDs instead.

When you add an item to a collection, it is the collection that is responsible for providing the next identity to be used. Whilst in this case it is not the collection itself that is generating the id, we should conceptually follow the same principle:

/**  
* Return the next identity  
*  
* @return UserId  
*/  
public function nextIdentity();  
You will have noticed that I’m creating the UserRepository right in the heart of the Identity portion of the application’s domain.

The UserRepository is very much part of the application’s business logic. However, the real implementations of the Repository are concerns of the infrastructure.

Therefore when we come to actually writing the implementation for the UserRepository we will house that file under the infrastructure namespace:

<?php namespace Cribbb\Infrastructure\Repositories;

use Doctrine\ORM\EntityRepository;  
use Cribbb\Domain\Model\Identity\UserRepository;

class UserDoctrineORMRepository extends EntityRepository implements UserRepository {}  
Conclusion
Repositories are important not only on a technical level, but also how we conceptionally think about the different layers of the application.

Using Repositories in our applications has a number of benefits.

Firstly, they prevent you from getting bogged down with the technical details of the infrastructure of the project.

Secondly, they make it much easier to test the various components of the application that interact with the database.

Thirdly, they provide a one-way dependency so the lines between layers are not blurred.

And finally, they provide the illusion of an in-memory collection so that the terminology of the persistent storage does not creep into the language of our applications.

For me, working with repositories just makes the data storage aspect of building web applications a whole lot easier!

This is a series of posts on building an entire Open Source application called Cribbb. All of the tutorials will be free to web, and all of the code is available on GitHub.


To view a full listing of the tutorials in this series

No comments:

Post a Comment