Шаблон репозитория - Как это понять и как он работает со "сложными" сущностями?
Мне трудно понять шаблон репозитория.
Есть много мнений на эту тему, как в шаблоне 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
Пример сверху я должен был сделать следующие шаги:
- принимать
toolSetDto
и проверь если нетnull
- Для каждого
tool*Dto
принадлежитtoolSetDto
а) Если есть действительный идентификатор, то конвертировать изDTO
вEntity
в противном случае создайте новую запись в базе данных
б)toolDescriptionDto
и преобразовать / сохранить его в базе данных или создать новую запись - После проверки вышеупомянутых экземпляров
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 происходит между вашими объектами БД и таблицами, а не между объектами приложения (тем более при работе с бизнес-объектами) и таблицами.