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

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

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

или же

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

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

// RestaurantOwnerService (Servlet)

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

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

    return null;
}

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

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

В основном изменить:

// RestaurantOwnerRepository

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

    RestaurantOwner restaurantOwner = this.get(sessionId);

    // .. getting restaurants ..

    return availableRestaurants;
}

в

// 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 на сервере и на стороне клиента, поскольку он содержится внутри общего проекта.

1 ответ

Решение

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

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

Таким образом, в очень простой настройке на стороне сервера у вас есть DB-Backend, доступ к данным через спящий режим в качестве постоянного уровня и служебный уровень в качестве службы отдыха. При такой настройке ваши спящие сущности распределяются между всем кодом на стороне сервера. Например, ваш сервисный слой конвертирует объекты в формат json. По рукам?

Ваша "продвинутая" настройка

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

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

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

Ответ: Нет, не совсем нормально возвращать DTO из слоя "хранилище".

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

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

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

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