Monday, February 11, 2013

Repository Pattern


Repository Pattern

Objectives

Use the Repository pattern to achieve one or more of the following objectives:
  • You want to maximize the amount of code that can be tested with automation and to isolate the data layer to support unit testing.
  • You access the data source from many locations and want to apply centrally managed, consistent access rules and logic.
  • You want to implement and centralize a caching strategy for the data source.
  • You want to improve the code's maintainability and readability by separating business logic from data or service access logic.
  • You want to use business entities that are strongly typed so that you can identify problems at compile time instead of at run time.
  • You want to associate a behavior with the related data. For example, you want to calculate fields or enforce complex relationships or business rules between the data elements within an entity.
  • You want to apply a domain model to simplify complex business logic.
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?

Example
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.

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

Child.java
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
          toyRespository.PutToysBackIntoBasket(toys);
     }
}


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
    @Override
    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
    @Override
    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.
Advantage
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