14

Currently I am developing a webapp where I have defined models implementing the Active Record pattern. Each model also is defined by an interface that specifies the Entity properties and makes it easy to inject it into other classes, specially useful for unit testing. I am looking forward to implement each model with a Repository pattern to abstract the database implementation.

e.g. Article:

ArticleInterface
- title
- content

ArticleRepositoryInterface
- getArticle(title)
- saveArticle(ArticleInterface)

ArticleRepository implements ArticleRepositoryInterface
- constructor(ArticleInterface)
- ArticleInterface getArticle(title)
- saveArticle(ArticleInterface)

Article implements ArticleInterface extends ActiveRecordModel

Both patterns are very popular in today web development frameworks, but It is not clear to me how to integrate them. The Active Record pattern by definition wraps a row in a database table, encapsulates the database access, mapping each object property to a database table, so

  • how should you integrate each model repository with the model that implements the AR ?

  • Are there any alternatives to using a model that implements the AR, inheriting all the database methods, and injecting it into a Repository wrapping all the AR database methods?

  • What are the best practices in this scenario?

If it adds any context to this question, I'm using Laravel and Eloquent.

2 Answers 2

7

The repository pattern:

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

The Data Mapping layer that you've chosen is Active Record. Ergo, the Repository is that software pattern that provides an additional layer of abstraction between your Active Record pattern and your business domain.

How should you integrate each model repository with the model that implements the AR?

By providing methods that return a collection-like interface to your business domain, using Active Record to retrieve the necessary results from the database.

Are there any alternatives to using a model that implements the AR, inheriting all the database methods, and injecting it into a Repository wrapping all the AR database methods?

You can use some other method for accessing the database, like Table Data Gateway, Row Data Gateway or Data Mapper, in place of Active Record.

What are the best practices in this scenario?

Those practices that best meet your software's functional and non-functional requirements in terms of performance and maintainability.

1
  • If anyone's curious (as I was), the definition at the top of this answer comes from Martin Fowler's book, Principles of Enterprise Application Architecture. More info can be found at martinfowler.com/eaaCatalog/repository.html. Commented Sep 5, 2019 at 13:33
8

Big difference between Active Record and Repository patterns is in my opinion the owner of the link between entity instance and underlying storage:

  • in Active Record, entity instance knows how and where to persist itself (this is what "active" means in my mind). That's why you can just call user.save() and it persists itself.
  • in Repository pattern, entity is more or less dumb POJO, it's the repository which manages its lifecycle. If you create a new instance of the entity, it's not magically persisted, you need to tell the repository to persist it.

Active Record is simpler but less flexible because it is attached to one backing storage.

In regards to who manages the entity's lifecycle, you need to choose one or the other.

But other than that you can create sort of a hybrid - e.g. your entities manage themselves (i.e. Active Record -> methods like .save() and .delete()), but then you have a repository which provides querying and mapping functionality without keeping track of "managed" entities (and without methods like .saveArticle()).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.