Tuesday, June 14, 2011

Repository Pattern

Repository means storage location for safety and preservation.  Its a single place where you can find related items. This terminology is used by some frameworks like Spring. But whats the need of repository?

Lets take an example. There is a big basket of toys. Toys contain Soft toys, wooden toys, miniature toys. If a kid wants miniature toys, he has to spill all the toys from the basket and separate the needed ones. Kid’s dad doesn’t want him to do that. He separates the miniature toys, that becomes a miniature toy repository, and gives it to child. Goal is never allow the kid to put hands on the basket.
Kid’s dad does the job of maintaining toy basket. Once the kid is done playing, he puts the toys back into the basket. When kid wants to play he gives the kid whatever toy he wants.  When dad brings a new toy for the kid, he is going to put that in the toy bag. In general, dad maintains the toy repository.

Repository pattern, as described in Domain Driven Design, in a typical java environment backed by frameworks like Hibernate and Spring.

public class Child   {
     public void Play(ToyRepositoryBase toyRespository) {     
         //Gets all the toys seperated by Dad
         List<Toy> toys = toyRespository.GetToys();
         //Now child starts playing
         System.out.println("Child is playing with " + toyRespository.GetType());
          //Child is done playing. Now dad puts back the toy into the bag

Get all the toys
//Toy is a abstraction of miniature toy or soft toy or wooden toy
public abstract class Toy


//Miniature toy is concrete class.
public class MiniatureToy extends Toy


Similarly we can have wooden toys, metallic toys and so on.
Get the toy repository

//This toy repository is abstract of miniature toy repository, wooden toy repository or soft toy repository
public abstract class ToyRepositoryBase  {
//Child calls this to get toys before starting to play
    public abstract List<Toy> GetToys();

     //One child is done playing, dad puts the toys back into the basket
    public abstract void PutToysBackIntoBasket(List<Toy> toys);

//Concrete class of miniature toy repository
public class MiniatureToyRepository : ToyRepositoryBase  {
 //Consider this as action performed by dad, 
//who gives the miniature toys to child
    public List<Toy> GetToys()
        List<Toy> miniatureToys = new ArrayList<Toy>();
        return miniatureToys;

    //This is action performed by dad. Once child is done playing,
    // he puts back the toys into bag
    public void PutToysBackIntoBasket(List<Toy> toys)
         //Here you can use cache or database
I have omitted other sub classes like WoodenToyRepository for brevity here.
We are not allowing the kid to put hands on the toy bag. Same way, business logic has no knowledge of database and  related implementation logic. All that business logic knows is how it can get the needed entity from repository, and how it can give the entity back to repository. It is the responsibility of repository to interact with the data source.
This pattern has several advantages.
  1. No duplicate codes needed. If you got another child who wants wooden toys, same logic works.
  2. Business logic is simplified, since its interactions is only with repository and repository entities.
  3. Less scope for errors
  4. Strong typing, since Miniature toy repository gives miniature toys.
  5. Easy to test.

No comments:

Post a Comment