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
Get all the toys
Similarly we can have wooden toys, metallic toys and so on.
Get the toy repository
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.
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.
- No duplicate codes needed. If you got another child who wants wooden toys, same logic works.
- Business logic is simplified, since its interactions is only with repository and repository entities.
- Less scope for errors
- Strong typing, since Miniature toy repository gives miniature toys.
- Easy to test.
No comments:
Post a Comment