Интерфейсы и ошибки в go

У меня вопрос об использовании интерфейсов при разделении бизнес-уровней и других уровней (например, уровня базы данных в моем случае). Я слышал, что интерфейсы желательно определять там же, где они используются.

В моем приложении есть RegistryService, который инкапсулирует логику регистрации и отмены регистрации рабочих в моем кластере приложений. У меня также есть структура Memberlist, в которой мои модели хранятся в связанном списке.

В моей реализации RegistryService я объявляю интерфейс workerProvider с такими методами, как SaveWorker, DeleteWorkerByID и т. д. Эти методы возвращают ошибки. В настоящее время эти ошибки определены в пакете memberlist. Однако я хочу абстрагировать эти ошибки, чтобы они не были тесно связаны с реализацией memberlist.

Стоит ли перенести интерфейс workerProvider в отдельный пакет и определить в нем новые типы ошибок?

    package registry
    
    import ( ... )
    var (
        ErrWorkerAlreadyRegistered = errors.New("worker is already registered")
    )
    
    type workersProvider interface {
        SaveWorker(ctx context.Context, endpoint string, zone string) (domain.Worker, error)
        DeleteWorkerByID(ctx context.Context, id uuid.UUID) (domain.Worker, error)
        ListWorkers(ctx context.Context) ([]domain.Worker, error)
        FindWorkerByID(ctx context.Context, id uuid.UUID) (domain.Worker, error)
    }
    
    type RegistryService struct {
        log *slog.Logger
        wp  workersProvider
    }
    
    func NewRegistryService(log *slog.Logger, wp workersProvider) *RegistryService {
        return &RegistryService{
            log: log,
            wp:  wp,
        }
    }
    
    func (reg *RegistryService) RegisterWorker(ctx context.Context, endpoint string, zone string) (domain.Worker, error) {
        worker, err := reg.wp.SaveWorker(ctx, endpoint, zone)
        if err != nil {
            emptyWorker := domain.Worker{}
            switch {
            case errors.Is(err, memberlist.ErrWorkerAlreadyExists):
                return emptyWorker, ErrWorkerAlreadyRegistered
            default:
                return emptyWorker, lib.WrapError(op, err)
            }
        }
    
        return worker, nil
    }
    package memberlist
    
    import (...)
    
    var (
            ...
        ErrWorkerAlreadyExists = errors.New("worker already exists")
            ...
    )
    
    type Memberlist struct { ... }
    
    func New() *Memberlist { ... }
    
    func (mlist *Memberlist) SaveWorker(_ context.Context, endpoint string, zone string) (domain.Worker, error) {
      ...
      return domain.Worker{}, ErrWorkerAlreadyExists
      ...
    }
    
    
    func (reg *Memberlist) DeleteWorkerByID(_ context.Context, id uuid.UUID) (domain.Worker, error) { ... }
    
    func (reg *Memberlist) ListWorkers(_ context.Context) ([]domain.Worker, error) { ... }
    
    func (reg *Memberlist) FindWorkerByID(_ context.Context, id uuid.UUID) (domain.Worker, error) { ... }

Не усложняйте слишком сильно, лучше всего позволить вашему коду самому решать, где он лучше всего подходит. Во время разработки вы автоматически увидите, где это лучше всего подходит. Но «общий» пакет — хороший выбор, например, apperrors или что-то в этом роде.

Christoph 27.07.2024 19:57
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
Создание API ввода вопросов на разных языках программирования (Python, PHP, Go и Node.js)
API ввода вопросов - это полезный инструмент для интеграции моделей машинного обучения, таких как ChatGPT, в приложения, требующие обработки...
1
1
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Меня всегда поощряли опробовать свои идеи, и это помогло мне многому научиться, поэтому я предлагаю вам сначала написать тесты, прежде чем вносить изменения. Затем вы можете создать свой пакет и посмотреть, соответствует ли он дизайну и будущим целям, которые вы задумали.

Но также спросите себя, с какими проблемами вы сталкиваетесь, если ошибки связаны со списком участников? Мешает ли это вам реализовать какую-то новую функцию? Является ли нынешний дизайн слишком сложным для работы? Эти вопросы помогут вам принять лучшее решение для себя.

Другие вопросы по теме