views:

47

answers:

1

I've noticed Repository is usually implemented in either of the following ways:

Method 1

void Add(object obj);
void Remove(object obj);
object GetBy(int id); 

Method 2

void Save(object obj);     // Used both for Insert and Update scenarios
void Remove(object obj);
object GetBy(int id);

Method 1 has collection semantics (which is how repositories are defined). We can get an object from a repository and modify it. But we don't tell the collection to update it. Implementing a repository this way requires another mechanism for persisting the changes made to an in-memory object. As far as I know, this is done using Unit of Work. However, some argue that UoW is only required when you need transaction control in your system.

Method 2 eliminates the need to have UoW. You can call the Save() method and it determines if the object is new and should be Inserted or is modified and should be Updated. It then uses the data mappers to persist the changes to the database. Whilst this makes life much easier, a repository modeled doesn't have collection semantics. This model has DAO semantics.

I'm really confused about this. If repositories mimic in-memory collection of objects, then we should model them according to Method 1.

What are your thoughts on this?

Mosh

A: 

I personally have no issue with the Unit of Work pattern being a part of the solution. Obviously, you only need it for the CUD in CRUD. The fact that you are implementing a UoW pattern, though, does nothing more than dictate that you have a set of operations that need to go as a batch. That is slightly different than saying it needs to be a part of a transaction. If you abstract your repositories well enough, your UoW implementation can be agnostic to the backing mechanism that you are using - whether it is database, XML, etc.

As to the specific question, I think the difference between method one and method two are trivial, if for no other reason than most instances of method two contain a check to see if the identifier is set. If set, treat as update, otherwise, treat as insert. This logic is often built into the repository and is more for simplification of the exposed interface, in my opinion. The repository's purpose is to broker objects between a consumer and a data source and to remove having to have knowledge of the data source directly. I go with method two, because I trust the simple logic of detecting an identifier than having to rely on tracking object states all over the application.

The fact that the terminology for repository usage is so similar to both data access and object collections lend to the confusion. I just treat them as their own first class citizen and do what is best for the domain. ;-)

joseph.ferris