Должны ли репозитории отвечать за сохранение связанных сущностей?

Должны ли репозитории отвечать за сохранение связанных сущностей?
Должны ли репозитории отвечать за сохранение связанных сущностей? - campfire_guy @ Unsplash

В чем я не уверен, так это в том, нужно ли иметь два разделенных репозитория [WorkspaceRepository / MemberRepository].

Как обычно, ответ зависит от ситуации.

Итак, связь Workspace <- Member навязывается программно от Workspace, который действует как корень агрегации. Это прекрасно. Но откуда берутся Members? Когда или как создаются, редактируются и перечисляются члены?

Когда мы добавляем членов в рабочие пространства, мы создаем членов заново? Когда мы удаляем их из рабочих пространств, удаляем ли мы Member из хранилища данных тоже? Или вместо этого мы удаляем отношение Workspace - member? Как отмечает @Cacnode, каков жизненный цикл Memeber?

Вы должны ответить на подобные вопросы, чтобы понять, нужен ли MemberRepository и каковы его возможности.

что помешает мне просто перенести бизнес-логику за пределы рабочей области?

Ничто не может помешать разработчику перенести/скопировать часть кода из компонента А в Б. Что вы можете сделать, так это направить потребителя API, не допуская обходных путей. Для этого ключевым моментом является инкапсуляция.

Если будет MemberRepository, как можно будет использовать функциональность в Workspace?

Никак. MemberRepository существует для управления members, а не workspaces. Он ничего не знает о рабочих пространствах1.

или WorkspaceRepository должен отвечать за сохранение и заполнение членов в рабочем пространстве?

.

Почему нет?

Репозитории - это абстракции (в идеале, предлагаемые ядром). Думайте о них как об интерфейсах. Ключ, таким образом, находится в реализации.

public class WorkspaceDBRepository implements WorkspaceRepository {
  private Dao<Workspace> workspaceDao; //<--- implementation detail
  private Dao<Member> memberDao; //<--- implementation detail
}
public class MemberDBRepository implements MemberRepository {
  private Dao<Member> memberDao;//<--- implementation detail
}

Допустим, нам наконец-то нужен список рабочих пространств, к которым принадлежит Member. Соединение "один-ко-многим", которое большинство ORM реализуют из коробки.

public class MemberDBRepository implements MemberRepository {
  private Dao<Member> memberDao;//<--- implementation detail
  private ReadOnlyDao<Workspace> workspaceDao;//<--- implementation detail
  //...
  //...
  //no public method with Workspace on its signature. Ever.
}

Это всего лишь примеры. Возможно, не самые элегантные, но они иллюстрируют мою мысль об абстракции против деталей реализации.


2

1: Application *Public Interface

Рекомендую посмотреть эти видео для лучшего погружения в вопрос:

Прикрепленное видео 1 - 5 Работа с базой данных с помощью Entity Framework Core

Прикрепленное видео 2 - Пишем с нуля Dependency Injection на C -, .NET, От "Hello World" до Autofac, NInject, MS DI


LetsCodeIt, 18 января 2023 г., 08:32