Well I’ve been trying to find out the difference between data mapper and repository, but up to now I still have not. It seems that Martin Fowler used to say “Repository is another layer of abstraction over the mapping layer where query construction code is concentrated”. It seems understandable but is still somewhat very ambiguous, and the example used in Fowler’s book was very confusing. I read this article on stackoverflow before, and it just made me even more confused: How is the Data Mapper pattern different from the Repository Pattern? Or maybe, they really are just the same thing under different names, like Domain Model and Entity?
I guess what I will need are simple explanations and concrete/practical examples on how the two patterns differ, and what a repository does what a data mapper doesnt, and vice versa. Do anyone of you know a good example on illustrating the concept of data mapper and repository? It will be better if it’s the same example, just one using data mapper and another using repository. Thanks, I’d very appreciate this, I am usually good at understanding and applying patterns but I just cant distinguish between these two.
Your Fowler quote seem to come from this page, where he also says that where you have a complex domain model it
can be worthwhile to build another layer of abstraction over the mapping layer where query construction code is concentrated.
He goes on to say
Client objects construct query specifications declaratively and submit them to Repository for satisfaction.
Also, data mappers deal with mapping a single entity, so if you want to be able to fetch several related objects you could have a repository that delegates to several mappers.
Edit: You might want to have a read of this SitePoint article, as it gives PHP examples of repositories and mappers being used together in exactly the way Fowler mentions.
In easy language: repository is a just a way to data-management, for example
<?php namespace Rtablada\LaravelFaq\Repositories;
interface FaqRepository
{
public function all($columns = array('*'));
public function newInstance(array $attributes = array());
public function paginate($perPage = 15, $columns = array('*'));
public function create(array $attributes);
public function find($id, $columns = array('*'));
public function updateWithIdAndInput($id, array $input);
public function destroy($id);
}
But, the Data-Mapper is a way for make more friendly communication with object, for example User data-mapper can be with register function, or even checkOnlineState
So in your word, a data mapper provides generic way of loading data, but repository is more specialized? If my user model contains data such as ID, username, email, date registration, etc. I will only need a mapper if the user is only fetched through ID, but will need a repository if client code can fetch users using username, email, date registration, etc?
Related objects? So lets say my user system needs to fetch related domain models such as UserProfile, Private Messages, etc, I should consider repository too since data mapper aint supposed to take care of relationships between domain models?
That is my understanding of what Fowler is saying (which seems to agree with code from the SitePoint article). I guess the thinking is that putting these specialised queries into the mapper would be giving it too much responsibility, so encapsulating them in a repository prevents client code from knowing anything about how the entities are retrieved from the datastore.
Hmm, this one I’m less sure about… certainly if you’re doing DDD then there’s the concept of ‘aggregate roots’ which are entities at the top of a specific object graph, and through which you access the other objects in the graph. In this situation, as I understand it, you might have a repository which loads blog posts along with the associated comments.
I should mention that although I’m interested in (and have been studying) things such as DDD and various architectural design patterns, I’m definitely not an expert, and most of what I’ve gleaned is from reading rather than practice so far, so please don’t take my comments as trying to be authoritative in any way! I’d certainly welcome corrections/input from anyone who thinks or knows differently.