Шаблон репозитория - Как это понять и как он работает со "сложными" сущностями?

Мне трудно понять шаблон репозитория.

Есть много мнений на эту тему, как в шаблоне Repository, сделанном правильно, но также есть и другие вещи, такие как Repository, это новый Singleton или снова как в " Не используйте DAO, используйте Repository" или просто возьмите Spring JPA Data + Hibernate + MySQL + MAVEN, где-то Репозиторий выглядит так же, как объект DAO.

Я устал от прочтения этого материала, потому что imho это не может быть такой сложной вещью, как это отражено во многих статьях.

Я вижу это так: кажется, что я хочу что-то вроде этого:

         ------------------------------------------------------------------------
         |                            Server                                    |
         ------------------------------------------------------------------------
         |                    |                        |                        |
Client <-|-> Service Layer  <-|->  Repository Layer  <-|-> ORM / Database Layer |
         |                    |                        |                        |  
         ------------------------------------------------------------------------

Service Layer принимает *DTO объекты и передает их Repository Layer это в основном не что иное, как "парень", который знает, как можно хранить сущность.

Например, предположим, что у вас есть набор некоторых инструментов (обратите внимание, что это просто псевдокод)

@Entity
class ToolSet {
  @Id
  public Long id;
  @OneToOne
  public Tool tool1;
  @OneToOne
  public Tool tool2;
}

@Entity
class Tool {
  @Id
  public Long id;
  @OneToMany
  public ToolDescription toolDescription;
}

@Entity
class ToolDescription {
  @Id
  public Long id;
  @NotNull
  @OneToOne
  public Language language

  public String name;
  public String details;
}

То, что я не получаю, это та часть, где я получаю ToolSetDTO объект от клиента.

Как я понял до сих пор я мог написать ToolSetRepository с методом ToolSetRepository.save(ToolSetDTO toolSetDto) который " знает, как хранить " ToolSetDTO, Но почти каждый учебник не проходит *DTO но Entity вместо.

Что меня беспокоит, так это то, что если ты возьмешь ToolSet Пример сверху я должен был сделать следующие шаги:

  1. принимать toolSetDto и проверь если нет null
  2. Для каждого tool*Dto принадлежит toolSetDto
    а) Если есть действительный идентификатор, то конвертировать из DTO в Entity в противном случае создайте новую запись в базе данных
    б) toolDescriptionDto и преобразовать / сохранить его в базе данных или создать новую запись
  3. После проверки вышеупомянутых экземпляров ToolSet (сущность) и настроить его для сохранения в базе данных

Все это слишком сложно, чтобы просто позволить сервисной функции (интерфейсу для клиента) справиться с этим.

То, о чем я думал, создавало, например, ToolSetRepository но вопрос здесь

  • Требуется ли ToolSet объект сущности или он использует DTO объект?
  • В любом случае: *Repository разрешено использовать другие объекты репозитория? Например, когда я хочу сохранить ToolSet но я должен хранить Tool а также ToolDescription первый - я бы использовал ToolRepository а также ToolDescriptionRepository внутри ToolSetRepository?
    Если так: Почему это не нарушает Шаблон Репозитория? Если этот шаблон в основном является слоем между службой и моей средой ORM, он просто "не чувствует себя правильным" для добавления зависимостей к другим *Repository занятия по причинам зависимости.

Я не знаю, почему я не могу обдумать это. Это не кажется сложным, но есть еще помощь, как Spring Data, Еще одна вещь, которая беспокоит меня, так как я действительно не понимаю, как это облегчает жизнь. Тем более, что я уже использую Hibernate - я не вижу преимущества (но, возможно, это другой вопрос).

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

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

1 ответ

Решение

Вы можете прочитать мой пост "Хранилище для чайников", чтобы понять простой принцип работы репозитория. Я думаю, что ваша проблема в том, что вы работаете с DTO, и в этом сценарии вы на самом деле не используете шаблон хранилища, вы используете DAO.

Основное различие между хранилищем и дао состоит в том, что хранилище возвращает только объекты , которые понятны вызывающему слою. В большинстве случаев хранилище используется бизнес-уровнем и, следовательно, возвращает бизнес-объекты. Дао возвращает данные, которые могут быть или не быть целым бизнес-объектом, то есть данные не являются допустимой бизнес-концепцией.

Если ваши бизнес-объекты - это просто структуры данных, это может быть подсказкой, что у вас есть проблема моделирования, т.е. плохой дизайн. Хранилище имеет больше смысла с "богатыми" или, по крайней мере, должным образом инкапсулированными объектами. Если вы просто загружаете / сохраняете структуры данных, возможно, вам не нужен репозиторий, достаточно orm.

Если вы имеете дело с бизнес-объектами, которые составлены из других объектов (совокупности), и этому объекту нужны все его части, чтобы быть согласованными (совокупный корень), то шаблон хранилища является лучшим решением, поскольку он будет абстрагировать все детали персистентности., Ваше приложение просто запросит "Продукт", а хранилище вернет его целиком, независимо от того, сколько таблиц или запросов требуется для восстановления объекта.

Исходя из вашего примера кода, у вас нет "реальных" бизнес-объектов. У вас есть структуры данных, используемые Hibernate. Бизнес-объект разработан на основе бизнес-концепций и вариантов использования. Хранилище позволяет BL не заботиться о том, как этот объект сохраняется. В некотором смысле, хранилище действует как "преобразователь / преобразователь" между объектом и моделью, которая будет сохранена. По сути, репо "сокращает" объекты до необходимых для сохранения данных.

Бизнес-объект не является объектом ORM. Это может быть с технической точки зрения, но с точки зрения дизайна, один моделирует бизнес-компонент, а другой - персистентный. Во многих случаях они не совместимы напрямую.

Самая большая ошибка заключается в том, чтобы спроектировать ваш бизнес-объект в соответствии с потребностями хранения и складом ума. И вопреки тому, во что верят многие разработчики, целью ORM является не сохранение бизнес-объектов. Его цель состоит в том, чтобы смоделировать базу данных "oop" поверх rdbms. Отображение ORM происходит между вашими объектами БД и таблицами, а не между объектами приложения (тем более при работе с бизнес-объектами) и таблицами.

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