Форум программистов, компьютерный форум, киберфорум
Java EE (J2EE)
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
5 / 5 / 2
Регистрация: 30.09.2012
Сообщений: 66

Архитектура Hibernate VS Паттерны (проектируем вместе:)

23.08.2016, 12:59. Показов 1149. Ответов 12

Студворк — интернет-сервис помощи студентам
Всем привет!

В Java недавно, поэтому прошу вашей помощи вникнуть в суть, если я чего-то недопонимаю, или же направить на путь истинный

Суть вот в чем:
Есть сайт с которого приходят разного рода заявки (Request)
Есть сущность Request (таблица в БД + entity-класс)
Есть две дочерних сущности, условно назовем их RequestType1, RequestType2 ... RequestTypeN, они расширяют функционал сущности Request (собственно это заявки разного вида), причем все RequestTypeX между собой могут пересекаться в некоторых данных (например 1 и 2 могут иметь связь с User, но остальные нет)

В RequestController приходит запрос на создание заявки заданного типа.
Каким образом реализовать наполнение данных в объекты из параметров, переданных с сайта.

У меня пока единственный вариант: это делать switch по типу и писать отдельно реализацию для каждого типа, но чую что это 100% говнокод

Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//так дело не пойдет
switch (params.get("type").toString()){
            case "type1":
                RequestType1 requestType1 = new RequestType1();
                ...
                break;
            case "type2":
                RequestType2 requestType2 = new RequestType2();
                ...
                break;
            ...
            ...
            default:
                return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
Проблема усложняется тем что типов может быть много и у каждого свои свойства, которые надо задать (мб отличные от других)

Буду благодарен за любые мысли и предложения
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
23.08.2016, 12:59
Ответы с готовыми решениями:

Гибкая архитектура и порождающие паттерны
У меня возник вопрос следующего характера. Предположим, что есть некоторый интерфейсный класс фильтра, есть реализации, наследованные от...

Архитектура и паттерны для разработки ADO.Net сервера
Добрый день! Более опытные разработчики может быть подскажут, как правильно организовать работу с SQL бд используя объекты ADO.Net. Я...

В указанном dsn архитектура драйвера и архитектура приложения не соответствуют друг другу
Добрый день. При запуске программы выскакивает вот такая вот ошибка. В чем может быть проблема и как ее исправить?

12
Эксперт Java
 Аватар для KEKCoGEN
2399 / 2224 / 565
Регистрация: 28.12.2010
Сообщений: 8,672
23.08.2016, 14:22
nightbuster, создайте класс RequestProcessorFacade. В нем создайте например Map<String, RequestProcessor>
Когда приходит реквест, вытаскивайте из этой мапы процессор (интерфейс) и выполняйте логику создания того реквеста который нужен.
0
5 / 5 / 2
Регистрация: 30.09.2012
Сообщений: 66
24.08.2016, 04:56  [ТС]
KEKCoGEN, у меня была подобная идея, но это своего рода повторение вышеописанной конструкции switch...case, и не поможет решить проблему дублирующего кода. То есть мне в любом случае придется для каждого интерфейса прописывать одинаковую обработку для одинаковых свойств. В Java это не решается?
Пример: у заявки типа 1 и 2 может быть связь с юзером, у 3 и 4 - нет такой связи, но есть, скажем, связь с оргинизацией.
Соответственно у Класса RequestType1 и RequestType2 есть метод
Java
1
2
3
public void setUserID(User userID) {
    this.userID = userID;
}
у остальных же такого метода нет, но есть другие общие методы.

То есть задача в том, чтобы написать некую конструкцию-сборщик, которая бы знала все доступные методы класса и применяла только те, которые возможно применить, то есть уйти от огромного количества дублирующего кода.

Возможно ли это в рамках данной задачи?

Добавлено через 18 минут
Другими словами мне очень не хватает динамического преобразования типов)
0
Эксперт Java
 Аватар для KEKCoGEN
2399 / 2224 / 565
Регистрация: 28.12.2010
Сообщений: 8,672
24.08.2016, 08:33
Цитата Сообщение от nightbuster Посмотреть сообщение
и не поможет решить проблему дублирующего кода.
плохому танцору как говорится.....для избежания дублирующего кода есть базовые классы, наследование и классы - утилиты. Вобщем инструментов полно.
0
5 / 5 / 2
Регистрация: 30.09.2012
Сообщений: 66
24.08.2016, 11:57  [ТС]
Цитата Сообщение от KEKCoGEN Посмотреть сообщение
для избежания дублирующего кода есть базовые классы, наследование и классы - утилиты
Я полагаю вы не совсем вникли в суть проблемы, и данное утверждение очень абстрактно.

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

Добавлено через 1 час 55 минут
Решил! Слава рефлексии!))

Создаем прокси-фабрику
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    public static class ProxyFactory {
        private Object object;
 
        public static ProxyFactory object(Object object) {
            return new ProxyFactory(object);
        }
 
        private ProxyFactory(Object object) {
            this.object = object;
        }
 
        public <T> T getAs(final Class<T> asClass) {
            checkComparability(object, asClass);
 
            return (T) Proxy.newProxyInstance(asClass.getClassLoader(),
                    new Class[]{asClass},
                    new ObjectProxy(object));
        }
 
        private <T> void checkComparability(Object object, Class<T> asClass) {
            for (Method method : asClass.getDeclaredMethods()) {
                Method found = method(method.getName())
                        .withParameterTypes(method.getParameterTypes())
                        .in(object).info();
 
                if (!found.getReturnType().equals(method.getReturnType())) {
                    throw new RuntimeException(String.format("Unable to find method '%s' in %s " +
                                    "with parameter type(s) %s with return type %s",
                            method.getName(),
                            object.getClass().getName(),
                            Arrays.toString(method.getParameterTypes()),
                            method.getReturnType().getName()));
                }
            }
        }
 
        class ObjectProxy implements InvocationHandler {
            private Object object;
 
            public ObjectProxy(Object object) {
                this.object = object;
            }
 
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return method(method.getName())
                        .withParameterTypes(method.getParameterTypes())
                        .in(object).invoke(args);
            }
        }
    }
Теперь для каждого набора методов создаем интерфейс, который будут реализовывать целевые классы.
Например для RequestType1 и RequestType2, имеющие методы setUserID и getUserID создадим интерфейс IUsable:
Java
1
2
3
4
5
public interface IUsable
{
    void setUserID(User user);
    User getUserID();
}
теперь при обработке полученных в контроллере параметров мы можем получить объект, реализующий этот интерфейс:
Java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
IUsable usable = null;
 
switch (params.get("type").toString()){
            case "type1":
                RequestType1 requestType1 = new RequestType1();
                usable = ProxyFactory.object(requestType1).getAs(IUsable.class);
                break;
            case "type2":
                RequestType2 requestType2 = new RequestType2();
                usable = ProxyFactory.object(requestType2).getAs(IUsable.class);
                break;
            default:
                return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
        }
 
        ...
 
        usable.setUserID(new User());
и в дальнейшем при добавлении юзера, обращаться к объекту usable, не задумываясь о его типе, разумеется проверив его существование перед этим, но это, думаю, описывать уже не стоит.

Данная конструкция лишена проблем с дублированием кода, и вся обработка идет одном централизованном месте.
Теперь при добавлении новых типов заявок не придется писать новые обработчики, достаточно описать интерфейс взаимодействия и добавить методы для заполнения данными.

PROFIT!!!

Надеюсь кому-то поможет. Замечания и предложения приветствуются.
0
Эксперт Java
 Аватар для KEKCoGEN
2399 / 2224 / 565
Регистрация: 28.12.2010
Сообщений: 8,672
24.08.2016, 12:02
Цитата Сообщение от nightbuster Посмотреть сообщение
Надеюсь кому-то поможет.
если только как пример того как нельзя писать код =)))

Надеюсь кто-то напишет вменяемую версию решения вашей проблемы. Как вы выше верно заметили в суть проблемы я не вникал, но рефлексивное решение в 90% случаев является неверным.
0
5 / 5 / 2
Регистрация: 30.09.2012
Сообщений: 66
24.08.2016, 12:13  [ТС]
Цитата Сообщение от KEKCoGEN Посмотреть сообщение
если только как пример того как нельзя писать код
Не претендую на оскар в номинации "лучший код", но пока это единственное рабочее решение, которое подходит для моей проблемы.

Если кто-то напишет лучше - отлично!

В данном же случае высказывание, что так писать нельзя - необоснованно, ибо не имеет аргументов

Добавлено через 5 минут
Да, кстати, не всегда то что плохо для одного места - плохо для другого и наоборот.

В данном случае я осознанно сделал выбор утинной типизации в пользу удобной и простой возможности масштабирования.
0
Эксперт Java
 Аватар для KEKCoGEN
2399 / 2224 / 565
Регистрация: 28.12.2010
Сообщений: 8,672
24.08.2016, 12:21
Цитата Сообщение от nightbuster Посмотреть сообщение
высказывание, что так писать нельзя - необоснованно
рефлексивный код труден для понимания и поддержки. Так же имеет тенденцию ломаться при добавлении каких-то казалось бы не связанных с ним изменений. Решать проблемы такого кода на продакшне это большая головная боль. Если вас устраивает рабочее решение, нет проблем. Зависит от ваших целей написания этого кода.


Цитата Сообщение от nightbuster Посмотреть сообщение
В данном случае я осознанно сделал выбор
вы не можете осознанно сделать выбор. У вас опыта недостаточно.

Вобщем давайте без оффтопа и холиваров. Поскольку код мне писать честно говоря лень, а без этого вас не убедить, дальше обсуждать смысла нет.

Цитата Сообщение от nightbuster Посмотреть сообщение
выбор утинной типизации
утиной с одной "н" пишется)
0
5 / 5 / 2
Регистрация: 30.09.2012
Сообщений: 66
24.08.2016, 12:27  [ТС]
Цитата Сообщение от KEKCoGEN Посмотреть сообщение
рефлексивный код труден для понимания и поддержки
Расскажите это разработчикам RoR

Цитата Сообщение от KEKCoGEN Посмотреть сообщение
имеет тенденцию ломаться при добавлении каких-то казалось бы не связанных с ним изменений
Данное решение применяется в очень узком месте, да и автоматическое тестирование никто не отменял

Цитата Сообщение от KEKCoGEN Посмотреть сообщение
Решать проблемы такого кода на продакшне это большая головная боль.
Вот тут не могу поспорить, так как мало опыта в J2EE, и решать проблемы на продакшне не приходилось, но несмотря на это, осознанный выбор я все-же делать могу, т.к. опыта маловато в J2EE а не в разработке в целом.

Собственно сюда люди и "приходят" для того, чтобы обмениваться опытом.
0
Эксперт Java
378 / 370 / 114
Регистрация: 30.06.2010
Сообщений: 1,445
26.08.2016, 12:47
nightbuster, в контроллер постите json?
0
5 / 5 / 2
Регистрация: 30.09.2012
Сообщений: 66
26.08.2016, 14:17  [ТС]
Цитата Сообщение от LeX BB Посмотреть сообщение
nightbuster, в контроллер постите json?
да.
0
Эксперт Java
378 / 370 / 114
Регистрация: 30.06.2010
Сообщений: 1,445
26.08.2016, 15:30
nightbuster, тогда в руки jackson-inheritance и смапить все в объекты. пример можно взять тут, пункт 2.2
0
5 / 5 / 2
Регистрация: 30.09.2012
Сообщений: 66
26.08.2016, 15:55  [ТС]
LeX BB, спасибо! Попробую в понедельник поковырять, на первый взгляд похоже на то что нужно!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
26.08.2016, 15:55
Помогаю со студенческими работами здесь

архитектура процессоров и компьютерная архитектура,Intel32. для первокурсников
сабж. кто чем может помочь юному,непонемающему в этой области человеку.желательно книгами.спасибо.

Использование hibernate.hbm2ddl.auto совместно с MySql8 и Hibernate
Это справедливо для H2, которая может быть настроена для распаковки в оперативную память ? Или же можно настроить таким образом работу...

Hibernate org.hibernate.HibernateException: Wrong column type
В модели было поле weight с типом double. Поменял на Integer и соответственно поменял в БД (postgresql) private Integer weight; ...

Hibernate Could not get constructor for org.hibernate.persister.entity.SingleTableEntityPersister
Доброго времени суток. Сталкиваюсь со всякими ошибками при добавлении данных в свою mysql бд. Вот код ошибки Exception in thread...

Ошибка "в указанном dsn архитектура драйвера и архитектура приложения"
Вот такая ошибка при нажатии на кнопку &quot;Проверить соединение&quot; Я прочитал, что это возможно из за того, что моя система 64, а...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
13
Ответ Создать тему
Новые блоги и статьи
Ритм жизни
kumehtar 27.02.2026
Иногда приходится жить в ритме, где дел становится всё больше, а вовлечения в происходящее — всё меньше. Плотный график не даёт вниманию закрепиться ни на одном событии. Утро начинается с быстрых,. . .
SDL3 для Web (WebAssembly): Сборка SDL3 и Box2D из исходников с помощью CMake и Emscripten
8Observer8 27.02.2026
Недавно вышла версия 3. 4. 2 библиотеки SDL3. На странице официальной релиза доступны исходники, готовые DLL (для x86, x64, arm64), а также библиотеки для разработки под Android, MinGW и Visual Studio. . . .
SDL3 для Web (WebAssembly): Реализация движения на Box2D v3 - трение и коллизии с повёрнутыми стенами
8Observer8 20.02.2026
Содержание блога Box2D позволяет легко создать главного героя, который не проходит сквозь стены и перемещается с заданным трением о препятствия, которые можно располагать под углом, как верхнее. . .
Конвертировать закладки radiotray-ng в m3u-плейлист
damix 19.02.2026
Это можно сделать скриптом для PowerShell. Использование . \СonvertRadiotrayToM3U. ps1 <path_to_bookmarks. json> Рядом с файлом bookmarks. json появится файл bookmarks. m3u с результатом. # Check if. . .
Семь CDC на одном интерфейсе: 5 U[S]ARTов, 1 CAN и 1 SSI
Eddy_Em 18.02.2026
Постепенно допиливаю свою "многоинтерфейсную плату". Выглядит вот так: https:/ / www. cyberforum. ru/ blog_attachment. php?attachmentid=11617&stc=1&d=1771445347 Основана на STM32F303RBT6. На борту пять. . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru