Что такое паттерн Repository и каково его назначение в Go-проектах?

Ответ

Паттерн Repository (Репозиторий) — это архитектурный паттерн, который изолирует слой доступа к данным от остальной части приложения (бизнес-логики). Его основная задача — предоставить интерфейс для работы с сущностями доменной модели, как будто они находятся в оперативной памяти, скрывая детали взаимодействия с конкретным хранилищем (базой данных, внешним API, файловой системой и т.д.).

В Go-проектах этот паттерн часто является частью "чистой" или гексагональной архитектуры.

Пример структуры:

// file: domain/user.go
type User struct {
    ID   int
    Name string
}

// file: internal/repository/user_repository.go

// 1. Интерфейс определяет контракт, не зависящий от реализации
type UserRepository interface {
    GetByID(ctx context.Context, id int) (*domain.User, error)
    Store(ctx context.Context, user *domain.User) error
}

// 2. Конкретная реализация для PostgreSQL
type postgresUserRepository struct {
    db *sql.DB
}

// Конструктор для создания репозитория
func NewPostgresUserRepository(db *sql.DB) UserRepository {
    return &postgresUserRepository{db: db}
}

// Реализация метода интерфейса
func (r *postgresUserRepository) GetByID(ctx context.Context, id int) (*domain.User, error) {
    // Логика выполнения SQL-запроса к PostgreSQL
    // ...
    return nil, nil
}

func (r *postgresUserRepository) Store(ctx context.Context, user *domain.User) error {
    // Логика INSERT или UPDATE
    // ...
    return nil
}

Ключевые преимущества:

  • Абстракция от источника данных: Бизнес-логика работает с интерфейсом UserRepository и не знает, хранятся данные в PostgreSQL, MongoDB или в памяти. Это позволяет легко менять хранилище данных, не изменяя бизнес-логику.
  • Улучшенная тестируемость: В unit-тестах для сервисного слоя можно легко подменить реальную реализацию репозитория на мок (mock), который имитирует поведение базы данных.
  • Централизация логики доступа к данным: Все запросы, связанные с определенной сущностью (например, User), собраны в одном месте. Это упрощает поддержку и отладку кода.