Skip to content
Repository Pattern — Explained with Examples

Repository Pattern — Explained with Examples

DodaTech Updated Jun 15, 2026 2 min read

The Repository pattern mediates between the domain and data mapping layers, providing a collection-like interface for accessing domain objects.

Repository is a design pattern introduced by Martin Fowler in Patterns of Enterprise Application Architecture. It abstracts data access behind a collection-like interface, so domain logic doesn’t depend on specific databases, ORMs, or storage mechanisms.

Why Repository Matters

Direct database calls scattered throughout business logic make code impossible to unit test, hard to refactor, and tightly coupled to a specific data source. The Repository pattern centralizes data access logic, making it swappable and mockable.

Real-World Analogy

A library catalog system. You ask the catalog (Repository) for a book — you don’t care whether the book is on the shelf, in storage, or borrowed from another branch. The catalog finds it and returns it. If the library reorganizes, your request method doesn’t change.

Example: Repository Pattern

from abc import ABC, abstractmethod
from typing import List, Optional

class User:
    def __init__(self, id: int, name: str, email: str):
        self.id = id
        self.name = name
        self.email = email

# Abstract repository — domain depends on this
class UserRepository(ABC):
    @abstractmethod
    def find_by_id(self, user_id: int) -> Optional[User]: pass
    @abstractmethod
    def find_all(self) -> List[User]: pass
    @abstractmethod
    def save(self, user: User): pass

# Concrete implementation for in-memory storage
class InMemoryUserRepository(UserRepository):
    def __init__(self):
        self._users = {}

    def find_by_id(self, user_id: int) -> Optional[User]:
        return self._users.get(user_id)

    def find_all(self) -> List[User]:
        return list(self._users.values())

    def save(self, user: User):
        self._users[user.id] = user

# Business logic uses the abstraction
class UserService:
    def __init__(self, repo: UserRepository):
        self.repo = repo

    def get_user_email(self, user_id: int) -> str:
        user = self.repo.find_by_id(user_id)
        return user.email if user else "not found"

Related Terms

DTO and DAO, Dependency Injection, ORM, Clean Architecture

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro