---
# System prepended metadata

title: ' Repository Pattern'

---


## Introduction

<!-- image of three layers  -->

![three layers](https://hackmd.io/_uploads/HyIKXlOu2.png)


### business logic (domain model layer)
- handler
  - API controller
  - event listener
- service
- aggregate

### data source (data access layer)
- database
  - raw query
  - ORM or ODM
- cache data
- file
  - TXT
  - XML
  - JSON
- web service
  - API

### repository

- decouple the business logic and the data access layers
- encapsulate the logic required to access data sources
  - (database) query syntax
  - (file) read/save/delete and deserialize/serialize data
  - (API) send request and parse response


## Pros & Cons

### pros
- improve maintainability and readability by swapping out the implementation details
- apply centrally managed, consistent access rules and logic
- migrating to a different persistence library, without affecting the calling code
- make code modular and testable 


### cons
- add an extra layer of abstraction
- typically need to create a repository for each entity


## Implementation

### generic repository interface and class

<!-- interface sample code -->
```javascript=
// generic repository interface

public interface IRepository<T> {

    IEnumerable<T> list();

    T findById(int id);

    void add(T item);

    void update(T item);

    void delete(T item);
}

``` 

<!-- class sample code -->
```javascript=
// generic repository class

public class OrderRepository implements IRepository<TOrder> {
    
    private OrderDataContext context;

    IEnumerable<TOrder> list() {}

    TOrder findById(int id) {}

    void add(TOrder order) {}

    void update(TOrder order) {}

    void delete(TOrder order) {}
}

```

### specific repository class (with expressive methods)

<!-- class sample code -->
```javascript=
// specific repository class

public class OrderRepository {
    
    private OrderDataContext context;

    TOrder[] listManyOrders(Predicate p) {}

    TOrder findOneOrderById(int orderId) {}

    void addOneOrder(TOrder order) {}

    void updateOneOrder(TOrder order) {}

    void deleteOneOrderById(int orderId) {}
}

```


## Questions

### generic repository or specific repository?
### is repository pattern essential?


## FAQ

### how to maintain atomic operations and consistency?
### what are the differences between repository pattern and DAO?
### 


## Terminology

- repository pattern
- Data Access Object (DAO)
- Object Relational Mapping (ORM)
- Object Document Mapping (ODM)
- [entity](https://blog.jannikwempe.com/domain-driven-design-entities-value-objects#heading-entities)
- [value object](https://blog.jannikwempe.com/domain-driven-design-entities-value-objects#heading-value-objects-vos)
- model (domain model)
- aggregate pattern
- unit-of-work


## References

- [Design the infrastructure persistence layer | Mircosoft Learn](https://learn.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-design#the-repository-pattern)
- [The Repository Pattern | Mircosoft Learn](https://learn.microsoft.com/en-us/previous-versions/msp-n-p/ff649690(v=pandp.10))
- [How you shouldn’t use Repository pattern | Roman Kinyakin](https://viblo.asia/p/how-you-shouldnt-use-repository-pattern-MLzkOzYEepq)