Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум программистов > Java: Design, Quality, Testing > Вопрос по архитектуре (EJB+GWT) |
Автор: fezzz 9.1.2013, 13:08 |
Уважаемые коллеги нужен адекватный взгляд на проблему ![]() Пришел работать в новую фирму, тут пишут большой корпоративный проект на ejb + gwt (компоненты от sencha gxt2-3). Хотел спросить совета, вернее дать какую-то оценку выбранному архитектурному подходу. Суть проблемы: На уровне данных вроде бы все ок. Объектная модель данных на базе jpa, тут вопросов нет. Но вот дальше начинается самое интересное - придуман некий слой DTO, на который возложено множество функций. Этот слой представляет из себя абсолютно зеркальную к модели данных (классы таблиц) структуру объектов, где каждый класс повторяет соответствующий класс таблицы. Плюс к этому реализованы два сервиса - dozer и combine. Dozer собирает на основе выбранных данных из объектов таблиц структуру из DTO. Причем не существует никаких (почти) механизмов ограничения выборки ветвей графа модели данных. Т.е. если мы например тянем список клиентов в комбобокс, где нужны по сути только их наименования, то dozer тащит все, что к этим клиентам привязано, все структуры, все коллекции и т.д. Т.е. думаю понятно. Есть правда механизм LazyList, который должен подгружать подцепленные коллекции по запросу, но он нигде почти не используется и распространяется только на коллекции. Второй сервис Combine наоборот пишет структуру DTO в базу данных, причем опять же нет никакой возможности управлять этим процессом, если была вытащена огромная структура, в ней поменяли одно поле, то пишется в базу все, с обходом всех связей. Кроме того, в базу сохраняется как бы слепок такой структуры. Если два пользователя допустим добавили какую-то информацию в какую-то структуру, ну допустим 2 разных записи контактной информации клиента, то сохранится только одна из них, потому что клиентское приложение посылает на сохранение всю структуру, которая пишется целиком, а не сливается с той, что в базе данных каким-то образом. Ну и кроме того, вся эта структура DTO одновременно является объектным слоем поставщиком данных для GUI. Все DTO наследованы от ModelData. Т.е. вся работа построена нехитрым образом - прочитали данные, преобразовали в DTO, сразу их показали в GUI, поменяли где надо, послали на запись. Как мне кажется этакий суррогат клиент-сервера. В общем я поработал с этим и пришел к выводу, что все это имеет право на существование только как ну некий трюк, может быть учебный пример или что-то такое, но разрабатывать серьезное приложение очень сложно. Хотел спросить совета, может я чего-то не понимаю (у меня небольшой опыт разработки web приложений), может это распространенный подход и все хорошо? Если что-то непонятно описал, задавайте уточняющие вопросы ![]() |
Автор: Nofate 9.1.2013, 14:45 |
Так примерно с GWT и приходится возиться. Чтобы лишние данные не гонять - DTO должны содержать необходимый минимум информации. Так это и есть клиент-сервер. На GWT у вас вполне толстый клиент (Rich Internet Application -RIA если быть точным). Клиент общается с сервером по-умолчанию средствами GWT RPC. Но могут быть и другие варианты, например REST+JSON или REST+XML. Поскольку мы не имеем возможности работать с ленивыми коллекциями хибера на клиенте (это ведь не JSP-представление, а практически автономное приложение, запущенное в браузере), приходится все данные конвертировать на входе и на выходе. |
Автор: fezzz 9.1.2013, 15:01 | ||
Необходимый минимум - это да! Но если Вы прочитали то, что писал я, в этом в случае DTO являются зеркальным отображение вообще всей структуры данных и тащат в себе всегда все связи. Разве это правильно? Я думаю, что DTO пишутся отдельно для каждого отдельного случая и содержат информацию по ситуации, а не копируют всю структуру данных. |
Автор: fezzz 9.1.2013, 17:30 | ||
Нет, это делается одним методом, который автоматом переносит граф данных из jpa в граф DTO. Клиент ворочает всеми этими структурами, что мне как-то дико. Я в принципе понимаю, что на GWT пишется довольно-таки толстый клиент, который за раз принимает довольно большие объемы данных, обрабатывает их и отсылает на сервер, но это как-то совсем уж крайний случай. Мне просто нужно понять насколько такое решение типично, может я дурак? ![]() Т.е. допустим есть у нас некий условный заказ. При его передаче на клиента, передается вообще все, что имеет хоть какое-то отношение к нему. Т.е. клиент вместе с его всеми полями, в которых может быть все, что угодно, начиная от структуры сотрудников клиента, заканчивая какой-нибудь историей изменений и прочее прочее. И так со всеми объектами, которые привязаны к заказу. Более того, если допустим есть некий общий список заказов, где нужно просто выбрать один и открыть его, то этот список это по сути коллекция вот таких вот монстро-образных структур, где каждая запись в гриде - это полный граф такого вот заказа, хотя в итоге-то будет выбран какой-нибудь один и с ним пользователь будет работать, а остальные просто не нужны. |
Автор: LSD 9.1.2013, 17:34 | ||
Это решение очень плохое. Плохо как минимум тем, что сервер не делает никаких проверок прав доступа, корректности данных и т.п. |
Автор: fezzz 9.1.2013, 17:39 | ||
Проверки доступа, кстати, реализованы ![]() Проверка логической целостности данных, если и делается, то исключительно на клиенте. |
Автор: baldina 9.1.2013, 18:10 | ||
это тоже нехорошо. получается, сервер и клиент связаны весьма доверительными отношениями. такое решение плохо устойчиво к ошибкам клиента и плохо расширяемо. а что говорят главные архитекторы проекта? |
Автор: fezzz 9.1.2013, 18:22 | ||
Человек, который все это написал, сейчас не работает в фирме. А у других программистов отношение весьма лояльное. Потому что, есть видимость того, что писать легко. Сейчас ведь как делается - создается например новая структура в базе, к ней пишется зеркальная DTO - точно такая же и вуаля, все это можно напрямую уже смотреть на клиенте, изменять и писать в базу. Все это похоже на db aware компоненты, которые были на делфи. Тяп ляп и готово. Проект не очень еще развит, но амбиции очень серьезные, вот сейчас начали встречаться с различными сложностями, но пока понимание того, что это работать не будет, еще не пришло. |
Автор: LSD 9.1.2013, 18:45 | ||
Вот вам и не авторизованный доступ к данным. Берешь дебагер JS и вперед. Как только проект подрастет наступите на грабли масштабируемости проекта. |
Автор: fezzz 9.1.2013, 18:50 | ||
Я уже на них стою. Размышляю теперь, как глаза остальным открыть. ![]() |
Автор: JDmitry 9.4.2013, 11:58 | ||||||||
Как раз Dozer и нужен для ограничения графа модели. Например, если вы создали класс Topic, содержащий список Comment, то ваш DTO объект должен содержать только нужные поля, как и в TopicDTO, так и в CommentDTO Например, если вам нужно показать только название раздела и его коментарии (без подгрузки коментариев), то обьект у вас будет выглядеть так (я маппинг делаю аннотациями - это не меняет сути)
И тогда вы можете сделать так
И в вашем topicDTO вы получите только часть структуры Таким образом мы вытягиваем только название и текст комментариев, игнорируя все остальные поля в вашем как в вашем Topic Entity объекте, так и в связанном в нем Comments. Даже если в Topic есть другие связи и сущности |