Нужна модель домена в сервисе в 3-х уровневой архитектуре? - PullRequest
1 голос
/ 30 марта 2020

Я создаю API Rest с Spring Boot и хотел бы прояснить концепцию моей архитектуры, чтобы посмотреть, может ли сообщество помочь мне.

Представьте, что в моей базе данных есть таблица с именем Person. Я монтирую архитектуру на основе трехслойной архитектуры. Общая схема будет выглядеть следующим образом:

  • С одной стороны, у меня есть PersonDao.java, который будет отвечать за доступ к базе данных для извлечения кортежей из таблицы Person , Для этого он использует класс PersonEntity.java, который содержит (в качестве атрибутов) все столбцы таблицы. PersonDao.java собирается вернуть объект из класса PersonModel.java. PersonModel.java - это класс, представляющий бизнес-модель Person.

  • С другой стороны, у меня есть PersonService.java, который отвечает за выполнение бизнес-логики c моего заявления. Эта услуга вызывает PersonaDao.java для доступа к информации, хранящейся в базе данных. PersonService.java работает с объектами класса PersonModel.java, поскольку этот класс представляет бизнес-объекты моего приложения. PersonService.java всегда возвращает PersonDto,java.

  • Наконец, PersonController.java. Этот контроллер будет тем, который предоставляет интерфейс подключения API Rest. Он всегда работает с DTO и общается с PersonService.java через DTO.

PersonController <-> (PersonDto) <-> PersonService <-> (PersonModel) <-> PersonDao <-> (PersonEntity) <-> DB

Вопрос: нужно ли использовать PersonModel.java класс, чтобы PersonService.java работал только с объектами этого класса? Или для PersonService.java было бы лучше работать напрямую с объектами из класса PersonEntity.java? Если я делаю это таким образом, это значит поддерживать принцип единой ответственности, чтобы каждый слой работал только с объектами своей сферы действия.

Если ответ таков, что PersonModel.java необходимо для поддержания принципа единой ответственности. ответственность каждого слоя. Изменится ли что-нибудь, если использовать JpaRepository? Если я задаю этот вопрос, то это потому, что во многих руководствах и примерах я вижу, что при использовании JpaRepository службы работают напрямую с объектами. В этом случае, разве мы не должны создавать класс, который представляет бизнес-объект для служб?

EDIT : В ответе на этот вопрос ( Spring Entities должен преобразовываться в Dto в обслуживании? ), архитектура, которая имеет смысл в моей голове, будет отражена, но, конечно, это не самая правильная вещь. Я пришел к выводу, что каждый слой будет использовать свои объекты. Копирование / вставка ответа:

Обычно у вас есть разные слои:

  • Постоянный слой для хранения данных
  • Бизнес-уровень для работы с данными
  • Уровень представления данных для представления данных

Как правило, каждый слой использует объекты своего вида:

  • Уровень сохраняемости: Репозитории, Сущности
  • Бизнес-уровень: службы, доменные объекты
  • Уровень представления: контроллеры, DTO

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

Заранее спасибо.

1 Ответ

1 голос
/ 31 марта 2020

Насколько я понимаю, ваш вопрос касается, в частности, слоев и их использования на уровне logic. (Таким образом, уровни presentation и data не являются частью вопроса).

О PersonModel

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

О PersonDto

DTO s, как следует из названия, действительно предназначены для передачи данных между клиентом (уровень presentation) и вашим API (уровень controller / boundary в пределах logic tier), которые используются для предоставления " дружественная к клиенту »презентация вашей доменной модели , чтобы как-то регулировать избыточную и недостаточную выборку (благодаря GraphQL это теперь почти не проблема). Таким образом, вашим классам бизнес-услуг вообще не нужно знать или иметь дело с DTO.

Кроме того, как вы уже упоминали, ради SRP бизнес-классы или дао-классы не должны иметь дело с дополнительным отображением данных (например, Dto <-> Model, Model <-> Entity) любым способом. Они уже выполняют определенную задачу на уровне логики c (ср. пограничный слой , сервисный уровень ).

О PersonEntity

Это то, что обычно представляет и сущность real из вашего проблемного домена и data уровня (например, таблица базы данных в СУБД или документ в № SQL). Так что

  • довольно часто называют классы сущностей без суффикса, например Entity. Просто используйте для него простое имя, например Person,

  • , чтобы классы сущностей содержали дополнительные аннотации (например, JPA), чтобы сделать их видимыми для ORM layer (например, Hibernate),

  • что классы сущностей не обязательно должны быть anemi c и фактически содержать некоторое дополнительное поведение (вероятно, то, что вы хотели сделать с вашим PersonModel классом) Например,

class Person {
  Date birthday;

  int getAge() { /* calculate age based on the birthday */ }

  boolean isAdult() { /* getAge() >= 18 */ }
}

Заключение

Вариант использования: создание Person объекта

Hinflug (исходящий рейс)

[Client] --> (data: JSON) --> <Deserialization as `PersonDTO`> --> <DTO Validation> --> [PersonController] --> <AutoMapping to `Person` entity> --> [PersonService] --> [PersonDao] --> <ORM and JDBC> --> <Entity Validation> --> DB

Примечание: <Validation> также можно сделать в контроллере вручную, но обычно для автоматизации используется API проверки бинов этот процесс на заднем плане . Хорошо, что вы можете использовать API Bean Validation для проверки ваших DTO и сущностей (например, с Hibernate Validator ).

Rückflug (обратный рейс)

DB --> <ORM and JDBC> --> [PersonDao] --> [PersonService] --> <AutoMapping to `Person` entity> --> [PersonController] --> <AutoMapping `Person` entity to `PersonDTO`>  --> <Serialization of `PersonDTO`> --> (data: JSON) -> [Client]  
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...