Должен ли я преобразовать объект в DTO внутри объекта репозитория и вернуть его на уровень сервиса?

я пытаюсь получить ответ на два очень похожие вопросы здесь:

должен ли я преобразовать объект в DTO внутри объекта репозитория и вернуть его на уровень сервиса?

или

можно ли возвращать объекты DTO из слоя репозитория?

прямо сейчас я застрял в своем сервлете (Servie Layer), который, например, пытается получить все Restaurant объекты из a RestaurantOwnerRepository:

// RestaurantOwnerService (Servlet)

@Override
@Transactional
public List<RestaurantDTO> getAvailableRestaurants() {

    List<Restaurant> availableRestaurants = restaurantOwnerRepository.getRestaurants(getSessionId());

    return null;
}

здесь Restaurant это @Entity аннотированный класс-что, кажется, первое, что я не должен делать, потому что уровень сервиса теперь знает об очень низкоуровневом объекте, который imho нарушает попытку абстрагировать мои данные в каждом слое.

это не было бы так, если бы я, например, преобразовал каждый Restaurant до RestaurantDTO - но должен ли я это сделать?

в основном изменения:

// RestaurantOwnerRepository

@Override
public List<Restaurant> getRestaurants(String sessionId) {

    RestaurantOwner restaurantOwner = this.get(sessionId);

    // .. getting restaurants ..

    return availableRestaurants;
}

to

// RestaurantOwnerRepository

@Override
public List<Restaurant> getRestaurants(String sessionId) {

    RestaurantOwner restaurantOwner = this.get(sessionId);

    // .. getting restaurants ..

    return ConvertEntity.convertRestaurants(availableRestaurants);
}

и в утиль ConvertEntity на каждый сущность такой например:

public class ConvertEntity {

    public static List<RestaurantDTO> convertRestaurants(List<Restaurant> restaurants) {
        // ...
    }

}

но это просто не кажется мне лучшим решением.. что мне здесь делать?


одна важная вещь, чтобы отметить было бы, что это происходит из проекта GWT. Это означает, что я использую, например,RestaurantDTO на сервере и на стороне клиента, поскольку он содержится внутри shared.

1 ответов


это более ясно теперь после вашего комментария. Давайте попробуем еще раз:

во-первых, некоторые пояснения: Ваш RestaurantOwnerRepository реализует шаблон репозитория. Ваш @Entity аннотированные объекты являются объектами гибернации, а также прокси DAO. Ваш RestaurantOwnerService - это GWT-сервис, который может возвращать только DTO, общий с клиентом и сервером.

очень простая настройка на сервере, у вас есть DB-Backend, доступ к данным через hibernate как персистентность слой, и слой сервиса как rest-сервис. В такой настройке объекты hibernate совместно используются для всего кода на стороне сервера. Например, уровень сервиса преобразует объекты в формат json. Договорились?

ваша "Расширенная" настройка

  • слой Персистирования
    • С Hibernate (доставка @ Entity-аннотированных объектов)
    • может быть, и другие вещи тоже
  • слой репозитория (неясно для вас что вернуть)
  • уровень обслуживания (сервлеты GWT, доставляющие DTOs, которые совместно используются с клиентской стороной)

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

Ваш вопрос: можно ли возвращать объекты DTO из слоя репозитория?

ответ: нет, на самом деле не очень хорошо возвращать DTO из слоя "репозиторий".

почему: 1. Ваш DTO-это объект домена, переданный в формат, который может быть отправлен на сторону клиента. Он имеет ограничения, так что некоторые стороны сервера в них нельзя использовать библиотеки. 2. Рассмотрим случай, когда вы также хотите предоставить другие слои сервиса. Может быть, интерфейс REST, может быть, другой GUI-фреймворк. Все они имеют свои собственные ограничения для передачи объектов домена. Вы действительно хотите дублировать слой репозитория для каждого слоя сервиса? 3. Рассмотрим случай, когда вы хотите расширить свой репозиторий / бизнес-уровень, чтобы он использовал вывод вашего RestaurantOwnerRepository. Вы действительно хотите работать над DTOs там?

вот почему создание DTO является целью уровня обслуживания. Таким образом, DTO разделяется между клиентской стороной и вашим уровнем обслуживания. В том же смысле вам нужны объекты, разделяемые между слоем сервиса и слоем репозитория. Я называю эти доменные сущности. Они возвращаются из слоя репозитория и используются слоем сервиса. Снова то же самое между слоем репозитория и слоем сохраняемости. Например, слой persistence возвращает объекты Hibernate которые используются на уровне репозитория.

в большинстве случаев можно распространять объекты из нескольких слоев вниз. Таким образом, вы можете вернуть свои Hibernate entites из слоя репозитория на уровень сервиса. Более новые версии GWT даже позволяют использовать JPA-сущности на стороне клиента со специальной настройкой. Таким образом, уровень сервиса может дополнительно возвращать объекты persistence.