Однією з причин, на яку я думаю, що ця дискусія виникає неодноразово, це тому, що здається серйозним болем у дупі взяти об’єкт зі всіма необхідними даними та перетворити його в об'єкт, який виглядає ідентичним або майже ідентичним тому, ти передаєш
Це правда, це ПІТА. Але є кілька причин (крім перерахованих вище) для цього.
- Об'єкти домену можуть бути дуже важкими і містять багато непотрібної інформації для дзвінка. Цей наліт уповільнює інтерфейс користувача через всі дані, передані, маршальовані / необмежені та проаналізовані. Якщо ви вважаєте, що ЗП матимуть численні посилання, що стосуються ваших веб-сервісів та дзвінків за допомогою AJAX або якогось іншого багатопотокового підходу, ви швидко зробите ваш інтерфейс повільним. Все це доходить до загальної масштабованості веб-сервісів
- Безпеку можна легко поставити під загрозу, викривши занадто багато даних. Як мінімум, ви можете відкрити адреси електронної пошти та номери телефонів користувачів, якщо не усунути їх з результату DTO.
- Практичні міркування: Щоб 1 об'єкт парадував як збережений доменний об'єкт AND DTO, він повинен мати більше приміток, ніж код. У вас виникне будь-яка кількість проблем із керуванням станом об’єкта під час його проходження через шари. Взагалі, це набагато більше, ніж PITA для управління, а потім просто виконувати набір копіювання полів з об’єкта домену в DTO.
Але ви можете досить ефективно керувати ним, якщо інкапсулювати логіку перекладу у колекцію класів перетворювачів
Погляньте на lambdaJ, де ви можете зробити "конвертувати (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);
}