Одна из причин, по которой я думаю, что эта дискуссия повторяется неоднократно, заключается в том, что мне кажется, что очень трудно получить объект со всеми необходимыми данными и преобразовать его в объект, который выглядит идентичным или почти идентичным ты сдаешь.
Это правда, это ПИТА. Но для этого есть несколько причин (помимо перечисленных выше).
- Доменные объекты могут быть очень тяжелыми и содержать много бесполезной информации для вызова. Это раздувание замедляет пользовательский интерфейс из-за того, что все данные передаются, маршалируются / разбираются и анализируются. Если вы считаете, что у FE будет множество ссылок, относящихся к вашим веб-сервисам и вызываемых с помощью AJAX или другого многопоточного подхода, вы быстро замедлит свой пользовательский интерфейс. Все это попадает в общую масштабируемость веб-сервисов
- Безопасность можно легко поставить под угрозу, подвергая слишком много данных. Как минимум, вы можете указать адреса электронной почты и номера телефонов пользователей, если не исключите их из результата DTO.
- Практические соображения: для 1 объекта, который будет выглядеть как постоянный объект домена и DTO, он должен иметь больше аннотаций, чем код. У вас будет множество проблем с управлением состоянием объекта, когда он проходит через слои. В общем, управлять PITA гораздо проще, чем просто копировать поля из объекта домена в DTO.
Но вы можете управлять им достаточно эффективно, если инкапсулируете логику перевода в коллекцию классов преобразователей.
Взгляните на lambdaJ, где вы можете выполнить команду 'convert (domainObj, toDto)', но есть перегрузка для использования с коллекциями. Вот пример метода контроллера, который использует его. Как видите, все выглядит не так плохо.
@GET
@Path("/{id}/surveys")
public RestaurantSurveys getSurveys(@PathParam("id") Restaurant restaurant, @QueryParam("from") DateTime from, @QueryParam("to") DateTime to) {
checkDateRange(from, to);
MultiValueMap<Survey, SurveySchedule> surveysToSchedules = getSurveyScheduling(restaurant, from, to);
Collection<RestaurantSurveyDto> surveyDtos = convert(surveysToSchedules.entrySet(), SurveyToRestaurantSurveyDto.getInstance());
return new RestaurantSurveys(restaurant.getId(), from, to, surveyDtos);
}