atomic-dependency-inversion-go.md 1.8 KB

Dependency Inversion в сервисном слое Go

Контекст: Сервисы (AuthService, PlaceService) зависели от конкретных типов репозиториев (*repository.PlaceRepo). Это делало юнит-тестирование невозможным без поднятия реальной БД.

Суть: Определяем интерфейсы в пакете сервиса (куда потребитель), а реализации остаются в repository (кто поставщик).

// services/places.go — определяем, что нужно сервису
type PlaceRepo interface {
    Create(ctx context.Context, place *models.Place) error
    GetByID(ctx context.Context, id string) (*models.Place, error)
    List(ctx context.Context, filter models.PlaceFilter) ([]*models.Place, error)
    // ...
}

// Конструктор принимает интерфейс
func NewPlaceService(placeRepo PlaceRepo) *PlaceService
graph LR
    S[services.PlaceService] -- depends on --> I[services.PlaceRepo interface]
    R[repository.PlaceRepo] -- implements --> I
    S ---|inject| R

Плюсы:

  • Моки для тестов — просто реализовать интерфейс
  • Нет циклических зависимостей
  • SRP соблюдён

Минусы:

  • Дублирование сигнатур методов (интерфейс + реализация)
  • Дополнительный файл/пакет

Связанные заметки: [[atomic-test-patterns-go]], [[architecture-overview]] Источник: Рефакторинг services/auth.go и services/places.go

#golang #architecture #testing #clean-architecture