Sobes.tech
Назад к вопросам
Junior — Middle
53

Какое преимущество дает применение паттерна Repository при работе с ORM системами?

Ответ от нейросети

sobes.tech AI

Что хотят услышать интервьюеры:

Паттерн Repository помогает отделить бизнес-логику от деталей ORM и доступа к базе данных. Это упрощает тестирование, замену ORM и поддержку кода. В итоге работа с данными становится более предсказуемой и централизованной.

Определение:

Repository — это слой, который предоставляет приложению единый интерфейс для чтения и записи данных, скрывая детали конкретной ORM, SQL-запросов или структуры таблиц. По сути, это посредник между доменной логикой и хранилищем данных.

При использовании с ORM репозиторий не дает бизнес-коду напрямую зависеть от моделей ORM и методов сессии. Вместо этого код работает с методами уровня предметной области, например get_by_id, save, delete, find_active_users.

Пример использования:

Допустим, есть сервис оформления заказа. Без Repository сервис напрямую обращается к ORM-моделям и сессии, а с Repository — только вызывает методы репозитория.

# ORM-модель
class User:
    def __init__(self, id, email, is_active):
        self.id = id
        self.email = email
        self.is_active = is_active


# Репозиторий
class UserRepository:
    def __init__(self, session):
        self.session = session

    def get_by_id(self, user_id):
        return self.session.query(User).filter(User.id == user_id).first()

    def get_active_by_email(self, email):
        return (
            self.session.query(User)
            .filter(User.email == email, User.is_active == True)
            .first()
        )

    def save(self, user):
        self.session.add(user)
        self.session.commit()


# Сервис
class OrderService:
    def __init__(self, user_repository):
        self.user_repository = user_repository

    def create_order(self, user_id):
        user = self.user_repository.get_by_id(user_id)
        if not user or not user.is_active:
            raise ValueError("User is not available")
        # логика создания заказа

Пояснение кода:

Код показывает, что сервис заказа не знает, как именно выполняется запрос к базе. Он вызывает get_by_id, а репозиторий уже сам решает, как работать с ORM-сессией и фильтрами.

Шаги работы:

  1. OrderService получает UserRepository через внедрение зависимости.
  2. Сервис запрашивает пользователя по user_id.
  3. UserRepository использует ORM для получения сущности из базы.
  4. Бизнес-логика сервиса остается чистой и не зависит от конкретной ORM-реализации.

Ключевые моменты:

  • Repository изолирует бизнес-логику от ORM и деталей хранения данных.
  • Код становится легче тестировать, потому что репозиторий можно подменить моками или фейками.
  • Упрощается замена ORM или изменение способа доступа к данным.
  • В одном месте концентрируются запросы к данным, что снижает дублирование.
  • Repository особенно полезен, когда в проекте сложные правила работы с данными и много обращений к БД.