Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should we save/update models in repository pattern?

i'm learning about repository pattern and i have seen a lot of examples where repository pattern is used for creation and update. Here is one example of repisotory interface.

interface RepositoryInterface
{
    public function all();

    public function create(array $data);

    public function update(array $data, $id);

    public function delete($id);

    public function show($id);
}

This repository interface is responsible for creating/retrieving and updating models.

But then, after a little better search, i found that people should avoid to persist data in repository and that repositories should act as collections and be used only for retrieving data. Here is the link .

Here is what they say there.

Probably the most important distinction about repositories is that they represent collections of entities. They do not represent database storage or caching or any number of technical concerns. Repositories represent collections. How you hold those collections is simply an implementation detail.

Here is one example of repository that only retrieve data.

interface BlogRepositoryInterface
{
    public function all();

    public function getByUser(User $user);
}

I am wondering what is the best practice for repository pattern?

If we should use repository only for retrieving models, how then we handle create/update/delete models ?

like image 264
Miljan Rakita Avatar asked Aug 03 '19 17:08

Miljan Rakita


2 Answers

Object persistance is totally allowed by Repository pattern.

From Martin Fowler's book Patterns of Enterprise Application Architecture (p.322):

A Repository mediates between the domain and data mapping layers, acting like an in-memory domain object collection. Client objects construct query specifications declaratively and submit them to Repository for satisfaction. Objects can be added to and removed from the Repository, as they can from a simple collection of objects, and the mapping code encapsulated by the Repository will carry out the appropriate operations behind the scenes.

The excerpt is clear: As Repository is a collection, you should be able to add and delete objects from it at your will.

The only concern I have is about your interface. You should break it in two or more as you will probably have objects that:

  • are not meant to be deleted
  • are not meant to be updated
  • are not meant to be inserted

Creating different interfaces would make your code meet the Interface Segregation Principle that states that no client should be forced to depend on methods it does not use.

Some examples:

  • Let's say you have a class that represents a state of your country. It's rare to see a country adding new states, deleting or changing their names frequently. Thus, the class State could implement an interface that has only the methods all() and show().

  • Suppose that you are coding an e-commerce. Deleting a Customer from database is not an option because all his data like buying history, searches, etc, would be lost. So you would do a soft delete, setting a flag $customer->deleted = true;. In this case, the class Customer could implement an interface that has only the methods all() and show() and other interface - or two interfaces - for the methods insert() and update().

like image 72
Caconde Avatar answered Oct 10 '22 20:10

Caconde


I think you misunderstood the sentences you quoted:

Probably the most important distinction about repositories is that they represent collections of entities. They do not represent database storage or caching or any number of technical concerns. Repositories represent collections. How you hold those collections is simply an implementation detail.

There is no statement saying that you should only use repositories for reading. The most important characteristic of repositories is that when you create or update an item with repositories, the changes may not be applied to the persistence layer immediately. The time changes are applied depends on the implementation of the repository.

A small note from me, we shouldn't have a method called create in the repository. As a collection, we add item to it, not create item. I usually have an add method instead of the create method in my repository interfaces. The creation should be the responsibility of a factory.

like image 32
Hieu Le Avatar answered Oct 10 '22 22:10

Hieu Le