design-patternsrepository-patterndatamapper

Single interface implementing both Data Mapper and Repository - any benefits?


Data Mapper is a layer of Mappers that moves data between objects and a database while keeping them independent of each other and the mapper itself.

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

Thus main job of Data Mappers is performing the mapping between objects and table rows and keeping the domain and database independent of each other, while main job or a Repository is to provide a more of an object-oriented view of the persistence layer and also keeping domain layer completely independent of the persistence layer.

a) As far as I can tell, both Data Mapper and Repository abstract the persistence layer,only difference being that Repository provides more of an object oriented view of the persistence layer?

b) In most implementations Repository sits on top of a Data Mapper layer, but in the following implementation ( From the book Architecting Net Solutions for the Enterprise ) the same interface functions as both a Data Mapper and a Repository ( thus it also masks the persistence layer as a collection ):

public interface IDataMapper<T>
{
/* Persistence */
void Create(T item);
void Update(T item);
void Delete(T item);

/* Repository */
IList<T> GetAll();
IList<T> GetAll(int index, int size);
int GetCount();
int GetCount(Query query);
T GetByKey(object key);
IList<T> GetByCriteria(Query query);
IList<T> GetByCriteria(Query query, int index, int size);
string TranslateQuery(Query query);
}

What are the advantages/disadvantages of such design compared to a design where Repository sits on top of data mapper layer?

thank you


Solution

  • I agree with @jgauffin when he says that the interfaces should be segregated. However, if you are sure that you are not exporting the interface to outside modules/apps (although interfaces are more likely to be used by others... that is why they are interfaces), you are also sure that no-one else is going to implement it, it is your own code only and even your code is not going to want to have mapper separated from repository, you can trade off and have them combined. It may lead to a more compact code... and probably tighter or enforced coupling. If these can be advantageous in certain situations, probably that is why the author of an Architecture book did it that way.

    However, again, I believe, the best way is to separate the interfaces as suggested by @jgauffin. You cannot be sure about clients of the interfaces and the extensions that may be required in future. Separating the interfaces would yield more maintainable and extensible code.