Thursday, December 18, 2008

Repository Entity Pattern

The repository pattern is too often under used when developing a domain model. I like to take a spin off the Domain Driven Design repository pattern and apply it to all collections within the domain.

Whenever the model needs a collection of entities, I use a repository. It is basically a glorified collection, controlling access to underlying entities in a type specific way. The main advantage to using a souped-up collection is that as needs change the implementation can be changed while maintaining the same interface. This abstraction also co-locates similar queries and query building logic into a single class structure, minimizing its duplication.

Writing access and bulk update queries involves a significant investment for new models. The abstraction of using a repository interface allows you to focus on the business logic early on, while working with small datasets and in memory collections. As the model interfaces begins to stabilize more focus can be in optimizing entity access.

For complex models that require uniquely optimized data access and updates. The repository pattern allows integrated query building logic to be separated and shared within it own class structure.

An anti-pattern to be aware of when using the repository pattern is to ensure that you don't try and combine aggregates and repositories together. A repository should not have any properties, only a collection of entities. Violating this significantly complicates the implementation and leads to role confusion exacerbating the problem.

A good definition of the pattern by Martin Fowler can be found on his website.
http://martinfowler.com/eaaCatalog/repository.html

There isn't many good examples of the repository pattern, so here is an example interface of what it might look like.

interface Repository extends Iterable {
void add(E entity);
void remove(E entity);
void clear();
E findById(String id);
}

interface SequentialRepository extends Repository {
E get(int index);
int indexOf(E entity);
}

interface ScoreRepository extends SequentialRepository {
List findScoresByCategory(Category cat);
void setScoreLimit(int limit);
Score getMax();
}


Reblog this post [with Zemanta]

No comments:

Post a Comment