Подтвердить что ты не робот

Образцовый шаблон - как его понять и как он работает с "сложными" объектами?

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

Есть много мнений по этой теме, например, в Образцовый шаблон, сделанный правильно, а также другие вещи, такие как Репозиторий - это новый синглтон или снова, как в Не используйте репозиторий использования DAO или просто возьмите 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), который "знает, как хранить" a ToolSetDTO. Но почти каждый учебник не передает *DTO, а Entity.

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

  • Возьмите ToolSetDTO и проверьте, не стоит ли null
  • Для каждого tool*Dto, принадлежащего ToolSetDTO
    a) Если имеет действительный идентификатор, то конвертируйте из DTO в Entity в противном случае создайте новую запись в базе данных
    b) toolDescriptionDto и конвертировать/сохранить его в базу данных или создать новую запись
  • После проверки этих выше instanciate ToolSet (entity) и настройте его для сохранения в базе данных

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

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

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

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