Здравствуйте, Blazkowicz, Вы писали:
B>- монструозными вычислениями в Service с нарушением инкапсуляции (внутри классов та же логика выглядит, читается и поддерживается проще) B>- необходимостью таскать за собой Service везде где вообще нужна логика — интерцеторы, GUI и пр.
Мне интересно как это вообще можно поддерживать. Ведь мне зачастую чтоб дернуть какой метод, нужно сделать это в контексте транзакции. А то и чтоб AOP обертка какая дергалась. Что, в Entity спрингом инжектить сервис чтоль? Я видел такое когда то в одном проекте — ужас! А логика то весьма может навороченная быть. И если метод вычисления возраста еще имеет смысл в сам класс Entity добавить, то метод рассчета каких нидь процентов по кредиту — это по любому внешний сервис, если ты не враг себе. Ибо для рассчета этих процентов возможно потребуется сделать запрос через 10 различных вебсервисов, чтоб это не тормозило, еще и кучу кеширования делать — это явно не в Entity пихать нужно. И сервис слой по любому будет.
B>Service это паттерн TransactionScript. Там живут бизнес транзакции. Вынос вообще всей логики из бизнес-объектов в Service приводит к трудно четаемому и слабо переиспользоваемому коду. И ещё к процедурному стилю.
Процедурный стиль это что то плохое? Лично я стили всегда мешаю, и пишу как в ООП, так и в функциональном и процедурном. А иногда и декларативном. Серебрянной пули нет. И во многих случаях как раз применение процедурного стиля — это как раз улучшение читаемости и повторной используемости.
E>>Кроме того, пограничные слои, которые оперируют с DTO — им 100 лет не сдались эти бизнес методы. Пограничные слои в основном визуализацией занимаются этой уже подготовленной DTO. Если нужны бизнес методы — будет вызов идти к сервису бизнес логики, а он как раз будет оперировать не с DTO, а с самой что ни на есть Entity, и все методы будут доступны. B>Это не так. Я уже приводил примеры выше. ORM Interceptor оперирует одними бинами, а бизнес логика в других (как предлагает автор статьи). Service туда тянуть? Чтобы посчитать, например, возраст? Так сервис же у нас оперирует BO бинами. Что делать?
Я не очень понимаю необъодимость отдельных бинов для бизнес логики, отличных от ORM. Соответственно этого слоя не будет да и все. А во view, где не нужно ничего считать и требуется только отобразить, возраст можно предоставлять уже посчитанным.
B>Аналогично на View слое. Вместо того чтобы дернуть вычислимое свойство у бина, мне нужно добавить это свойство в бин представления и убедится что его значение всегда синхронизировано с остальными данными.
На вьюшку крайне желательно чтоб все попадало уже засинхронизированным
Re[20]: Маппинг объектов с помощью java-object-merger
Здравствуйте, Blazkowicz, Вы писали:
GT>>А, давайте рассмотрим оба варианта.
Кажется вы забыли ответить
B>Здравствуйте, GreenTea, Вы писали:
GT>>Маппинг на конфигурация это что? Конфиги писать? B>Пока ваш маппинг не имеет compile time check это всё тот же конфиг. B>Только на аннотациях мы не можем иметь больше одного конфига. B>А без них можем.
Кстати я щас подумываю встроить в маппер функцию тестирования маппинга. Суть в следующем. Модель заполняется случайными данными, все его чайлдовые бины, коллекции, тоже заполнятся рекурсивно. Целевой объект пуст. Потом вызвается map, и после этого идет проверка чтобы все поля целевого объекта были замаплены. Таким образом можно написать юнит тест в котором просто вызвать данный метод.
GT>>Тоесть правильно я понял, вы знаете 1000 и 1 способ решать задачу на всех технологиях, причем способы различные? Я же предлагаю один унифицированный способ (раздаление на слои и использование маппера), которой будет подходить для всех технологий. B>Нам повезло и мы Java, где вольны выбирать лучшие из инструментов. В противном случае, пришлось, бы, действительно, решать все проблемы введением всё новых и новых слоёв.
Re[8]: Маппинг объектов с помощью java-object-merger
Здравствуйте, elmal, Вы писали:
E>Мне интересно как это вообще можно поддерживать. Ведь мне зачастую чтоб дернуть какой метод, нужно сделать это в контексте транзакции.
Не хочу никого задеть. Но когда пишешь только Web проекты вида запрос-ответ, то оно кажется именно так. Когда тебе нужна одна и та же логика в нескольких слабо связаных звеньях приложения, то смотрится всё в ином свете. У меня сейчас GUI, Business Transaction, Cross-server Data Synchronization. Они друг с другом не пересекаются. 1й работает на клиенте, второй на сервере, третий на отдельном сервере. И всем нужно использовать одну и ту же бизнес-логику, которая просто вычисляется из свойсв бизнес-сущностей. Нафиг мне транзакция для вычисления состояния объекта?
E>А то и чтоб AOP обертка какая дергалась. Что, в Entity спрингом инжектить сервис чтоль? Я видел такое когда то в одном проекте — ужас! А логика то весьма может навороченная быть.
Что-то тебя понесло не в ту степь.
E>И если метод вычисления возраста еще имеет смысл в сам класс Entity добавить, то метод рассчета каких нидь процентов по кредиту — это по любому внешний сервис, если ты не враг себе. Ибо для рассчета этих процентов возможно потребуется сделать запрос через 10 различных вебсервисов, чтоб это не тормозило, еще и кучу кеширования делать — это явно не в Entity пихать нужно. И сервис слой по любому будет.
У меня масса методов, которые вычисляются по состоянию сущности. И в зависимости от состояния, тот или иной слой принимает решение. Никакие транзакции там не нужны.
E>Процедурный стиль это что то плохое? Лично я стили всегда мешаю, и пишу как в ООП, так и в функциональном и процедурном. А иногда и декларативном. Серебрянной пули нет. И во многих случаях как раз применение процедурного стиля — это как раз улучшение читаемости и повторной используемости.
Ты предлагаешь ВСЕ методы вынести из Entity в Service. И как у нас будет ООП в этом случае работать? Параллельно с иерархией сущностей будет аналогичная иерархия сервисов?
E>Я не очень понимаю необъодимость отдельных бинов для бизнес логики, отличных от ORM. Соответственно этого слоя не будет да и все. А во view, где не нужно ничего считать и требуется только отобразить, возраст можно предоставлять уже посчитанным.
Это не я придумал. Это в статье написано.
E>На вьюшку крайне желательно чтоб все попадало уже засинхронизированным
"Крайне желательно". А вычисление по текущему состоянию на View мне гарантирует что состояние всегда синхронизировано.
Re[11]: Маппинг объектов с помощью java-object-merger
Здравствуйте, GreenTea, Вы писали:
GT>Маппить поле на коллекцию, это как? Можете поподробнее, или лучше напишите кодом.
Ну, вот так. В Legacy системе есть поля Rate1, Rate2,... Rate16. В новой системе это коллекция.
GT>Вопрос, откуда эти константы будут браться? Если не из Availability и специфичны только для этого запроса то: засетить их вручную после маппинга. GT>Ибо это уже не функция маппера. Его задача перегнать данные из одного объекта в другой.
Я специально упростил код. Потому что там есть ещё две строки.
Здравствуйте, GreenTea, Вы писали:
GT>>>А, давайте рассмотрим оба варианта. GT>Кажется вы забыли ответить
"Некада". Позже будет время, найду пример и покажу.
GT>Кстати я щас подумываю встроить в маппер функцию тестирования маппинга. Суть в следующем. Модель заполняется случайными данными, все его чайлдовые бины, коллекции, тоже заполнятся рекурсивно. Целевой объект пуст. Потом вызвается map, и после этого идет проверка чтобы все поля целевого объекта были замаплены. Таким образом можно написать юнит тест в котором просто вызвать данный метод.
Та ну на. Сделайте маппинг на лямбдах. Большего и не нужно.
Re[12]: Маппинг объектов с помощью java-object-merger
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, GreenTea, Вы писали:
GT>>Маппить поле на коллекцию, это как? Можете поподробнее, или лучше напишите кодом. B>Ну, вот так. В Legacy системе есть поля Rate1, Rate2,... Rate16. В новой системе это коллекция.
Коллекция чего? Значений того же типа что и Rate1, Rate2,... Rate16? Можно подумать над тем чтобы добавить возможность такого маппинга, только есть
сомнения в том, что это понадобится очень часто. Но, приниципально не вижу проблемы научить маппер делать такое.
GT>>Вопрос, откуда эти константы будут браться? Если не из Availability и специфичны только для этого запроса то: засетить их вручную после маппинга. GT>>Ибо это уже не функция маппера. Его задача перегнать данные из одного объекта в другой. B>Я специально упростил код. Потому что там есть ещё две строки. B>
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, GreenTea, Вы писали:
GT>>>>А, давайте рассмотрим оба варианта. GT>>Кажется вы забыли ответить B>"Некада". Позже будет время, найду пример и покажу.
GT>>Кстати я щас подумываю встроить в маппер функцию тестирования маппинга. Суть в следующем. Модель заполняется случайными данными, все его чайлдовые бины, коллекции, тоже заполнятся рекурсивно. Целевой объект пуст. Потом вызвается map, и после этого идет проверка чтобы все поля целевого объекта были замаплены. Таким образом можно написать юнит тест в котором просто вызвать данный метод. B>Та ну на. Сделайте маппинг на лямбдах. Большего и не нужно.
С удовольствием, только расскажите как это И еще, лябды ж буду только в java 8, а как быть проектам на java 6-7 ?
Re[18]: Маппинг объектов с помощью java-object-merger
Здравствуйте, Blazkowicz, Вы писали:
B>Здравствуйте, GreenTea, Вы писали:
B>>>То что на аннотациях нельзя замапить один объект в два разных JSON представления это как раз и есть косяк аннотаций и используемого фреймверка. GT>>"То что на аннотациях нельзя замапить один объект в два разных JSON представления это как раз и есть косяк аннотаций" B>Не обязательно копировать мои цитаты, чтобы обернуть в кавычки. Движок форума подсвечивает цитаты, когда они начинаеются с >.
GT>>о чем я и говорю! Вешая аннотации на сущности мы задаем только 1 способ маппинга, а если нужно мапить одну и ту же сущность в разных местах двумя, тремя и более способами, то тут аннотации не помогут. B>И на помощь приходят конфиги и маппинг вне классов.
Если честно то не уверен что все технологии подрреживают конфигурацию без аннотаций. И хотел бы я посмотреть на все эти конфиги.. Как по мне то поддерживать их, это кромешный ужас. Во-первых, не наглядно. На вью объект глянул — и сразву видно что будет передаваться. А там какой то специфичнй для технологии конфиг.. В одной технологии однин конфиг, в другой — другой конфиг. Бред какой-то.
GT>>Зато если ввести слой представлений (вьшек) и использовать маппер — то проблемма решается. А как вы решаете данною проблему, дождусь я от вас ответа или нет? B>Вы требуете конкретики об абстракции? О какой конкретно технологии речь? JSON? HTML? Swing GUI? SOAP? Отчеты? Для каждого решается вопрос по-своему.
GT>>Повторяю: вы не можете JSON маппером вешая аннотации настроить более 1 сособа, как эта сущность будет мапится. B>Могу без аннотаций. Могу с аннотациями и security фильтром. Много как могу, в зависимости от требований системы.
Re[13]: Маппинг объектов с помощью java-object-merger
Здравствуйте, GreenTea, Вы писали:
GT>Здравствуйте, Blazkowicz, Вы писали:
B>>Здравствуйте, GreenTea, Вы писали:
GT>>>Маппить поле на коллекцию, это как? Можете поподробнее, или лучше напишите кодом. B>>Ну, вот так. В Legacy системе есть поля Rate1, Rate2,... Rate16. В новой системе это коллекция.
GT>Коллекция чего? Значений того же типа что и Rate1, Rate2,... Rate16? Можно подумать над тем чтобы добавить возможность такого маппинга, только есть GT>сомнения в том, что это понадобится очень часто. Но, приниципально не вижу проблемы научить маппер делать такое.
Что-то вылетело из головы, что это уже реализовано. Стравим аннотацию над коллекцией, и конвертер
@MapFromMany("rate1", "rate2", "rate3" ... "rate16")
@Converter(MyCollectionAssembler.class)
MyCollectionAssembler.class — тут соберете все объекты из полей в коллекцию.
Здравствуйте, GreenTea, Вы писали:
GT>Чуть расширенная версия статьи с хабра, для тех кто еще не видел GT>http://brunneng.blogspot.com/2013/10/java-object-merger.html
Потратив немного времени на изучение вопроса, вынужден признать, что object mapping имеет смысл, как раз в тех случаях когда используемые инструменты не дают возможности реализовать разнообразный маппинг для одних и тех же сущностей.
SOAP/WSDL выше не самый лучший пример. Например CXF позволяет задать маппинг через XML а не аннотации, соответственно это даёт возможность заиметь 3 контекста с разными маппингами, в зависимости от нужд. Я даже могу тоже самое через JAXB реализацию com.sun.* провернуть. Просто маппинг там придется сленка расковырять через рефлексию. Но задача решаема.
Но тем неменее, возможно, существуют инструменты, где так просто тоже самое не реализовать. Например недавно столкнулся с JavaFX 2 вплотную. Где совершенно не понятно какая стратегия лучше, то ли MVVM, с дублированием сущностей, то ли использование javafx свойств, там где они отрадась ненужны. В случае MVVM, возможно, маппер бы и подлечил.