Как стать автором
Обновить
-5
0
Валерий Лиховских @vl65

Программист, Архитектор, Руководитель проекта

Отправить сообщение

У меня нет в коде имен, у меня есть соглашение. И в базе я не буду что либо переименовывать. Я назову поле в базе, так как оно приходит от внешней системы. Как я понимаю это имя "status". Этого достаточно, чтобы все отработало автоматически. И в коде не будет ни одного имени поля и отработают две транзакции, если Вам так нужно.

У меня код давно написан и код который выполнят любую транзакцию написан. Мне все равно сколько транзакций выполнять. Одну, две, десять. Абсолютно все равно. У Вас эти "2 транзакции" похоже вызывают большую проблему, что Вы постоянно к ним возвращаетесь.

Мешаете, ибо при изменении одного слоя, Вам нужно обязательно менять другой слой. Иначе все сломается.

В вашем коде логика тесно связана с программной моделью и моделью данных все схлопнуто в один монолитный слой - одно без другого не работает. Не можете заменить модель данных, не можете заменить программную модель. Посмотрите на реализацию драйвера БД, на реализацию собственного кода. О повторности использования вашего кода говорить вообще не приходиться.

Вы зациклились на своем понимании "хешмапам". Если написан универсальный код c "хешмапами", который можно использовать многократно использовать имеет это значение? Нет. Вам не надо же каждый раз повторять этот код? Не надо. Да ваш движок внутри тоже использует "хешмапами", в которых связывает соответствие одного другому. Только ваш движок не обеспечивает повторность использования вашего кода и, еще раз почеркну, объединяет совершенно разные слои вашего и чужого кода в один монолит.

2 ваших транзакции (хотя не понятно почему две, а не одна, получили ошибку при HTTP вызове чего там перед второй транзакцией) это частный случай (отклонение) и если у вас реализован код, который выполняет любую транзакцию, что что вам мешает его вызвать дважды с разными параметрами? Будет две строки.

Драйвер ДБ отличный пример решения частной задачи в общем виде создания узкоспециализированного программного слоя, который реализован на разработанной спецификации (соглашении). Кстати, драйвер БД ни как не привязан к предметной области, что обеспечивает высокую повторность его использования. Вы можете заменить драйвер одной СУБД на другой в любой момент времени. И если ваше ПО написано правильно, то оно останется в рабочем состоянии. Как "узкоспециализированный программный слой" драйвер БД всех ваших задач не решает, иначе вам не пришлось писать собственный каждый раз собственный программный код.

Так может все же стоит задуматься над соглашениями собственного программного кода хотя бы для того чтобы самому меньше его писать?

:-) Если так делают все, это не значит что нельзя делать лучше. Вот ораклисты не могут работать без ID, построчной обработки и ORM. Дай им настоящую реляционную модель данных, а не индексную (ID это по сути номер строки), все у них возникает крушение мира.

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

Зациклены на своей логике и понять плюсы других решений уже не в состоянии.

Еще раз для непонятливых, кто ставит минусы и все прочие ...

ORM это плохо тем, что фактически связывает два программных слоя в один. Программные слои - это слой хранения данных и слой сервера приложения.

Можно строить приложения без ORM? Можно. Данная задача решается в общем виде и основной элемент этого решения выработка соглашений. Соглашения позволяют решить задачу в общем виде не привязываясь к структуре данных и предметной области. Бывают разного рода отклонения? Бывают. Этих отклонений, как правило, не много в конкретной реализуемой задаче и они решаются в подавляющем числе случаев достаточно просто в рамках общего решения.

Кстати, ORM, а точнее реализации ORM, так же построено на соглашениях, только эти соглашения жестко приписываются в коде и состоят из имен классов, имен методов, аннотаций, деклараций и т.п., что выливается в лишний объем кодирования. Лишний объем кодирования затрудняет модификацию ПО (с этим никто спорить надеюсь не будет). Реализация в идеологии ORM привязывает код к предметной области, следовательно повторность использования практически нулевая.

Итак резюмирую недостатки ORM:

  1. избыточный объем кодирования

  2. ресурсоемкость модификации

  3. отсутствие повторности использования кода

  4. программная реализация соглашений

Можно реализовать соглашения как то иным способ, чем в универсальном сервисе? Можно, с учетом ваших потребностей. Можно идею соглашений применить где то еще? Можно. Например идею соглашений применил в реализации конфигурации приложения. Сразу отпала необходимость в каких либо классах фабриках и структура конфигурационного файла может иметь произвольный вид и этот код может быть повторно использован вообще в любых приложения. И в любой момент структура конфигурационного файла может быть модифицирована под новые требования практически ничего не затрагивая в коде.

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

См код сервиса, я ничего не прячу

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

Вот скажи мне пожалуйста чем моя строка

save(date);

отличается от твоей

this.entityManager.save(cart);

Я тебе показал, то что так настойчиво просишь меня сделать. Как может быть реализован этот мой метод save, можно увидеть в коде моего примера на GitHub.

ИТОГ !!! Можно работать без ORM и код будет значительно короче твоего текущего.
Вопросы есть?

Пример полностью см в GitHub

А где твой то?

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

save(date);
client.getStatus(data);
save(date);

Так устроит? :-) Все го три стоки, я чемпион :-)

Даже ваша новая логическая схема неверна. HTTP-запрос вы добавили, а 2 транзакции опять пропустили. Запись в БД должна быть и до HTTP-запроса, и после. В этом и есть основная особенность этой логики.

:-) это вводную Вы озвучили впервые

ArrayList transaction = new ArrayList();
transaction.add(...);
...
transaction.add(...);
database.execute(transaction);

int status = client.getStatus(data);
data.put("status", status);

transaction = new ArrayList();
transaction.add(...);
...
transaction.add(...);
database.execute(transaction);

так устроит?

:-) так устроит

int status = client.getStatus(data);
data.put("status", status);

Откуда что вызывается совершенно все равно, какая должна работать логика то же при разбиении ПО на "кубики"

Сейчас логическую схему моего универсального сервиса можно представить так

прием данных - подготовка данных для записи - Datadase - DataSource - JDBC драйвер - БД

Datadase - это некоторая "хитрая" настройка над спецификаций javax.sql, которая упрощает работу с БД из приложения. Но речь сейчас не о ней.

Для встраивания вашего вызова чего там по HTTP можно выстроить следующую логическую схему

прием данных - запрос по HTTP - подготовка данных для записи - Datadase - DataSource - JDBC драйвер - БД

Повторю варианты реализации

  1. Реализовать Filter в спецификации сервлетов

  2. Реализовать аналог Filter вместо кубика запрос по HTTP

  3. Реализовать класс расширения, который дает переопределить слой подготовка данных для записи и в нем сперва выполнить запрос по HTTP.

  4. Дополнить "универсальный" сервис дополнительными свойствами, определение которых позволит сделать запрос по HTTP

И все будет работать без ORM

Достаточно?

Я вам уже кучу вариантов набросал как можно реализовать выше настойчивое желание что то запрограммировать, выбирайте любой понравившийся.

Кстати, если Вы так стремитесь чем то "мериться".

Такой вопрос. А может ли ваш код работать с БД без драйвера этой СУБД?

Код моего примера может. :-)

Не бросайтесь словами - некрасиво выглядит. И слово "ПРИМЕР" Вы, похоже, все же не понимаете.

Конечно мой пример не делает вашу специфическую логику. Он про нее ничего не знал на этапе его разработки. У моего демо проекта совершенно другая цель, которую он отлично демонстрирует - работу с БД любой структуры без ORM. И при чем тут ваша специфическая логика, на которую вы Все время упираете мне совершенно не понятно.

Кстати, в моем проекте предусмотрены классы расширения, при реализации которого можно реализовать то, что Вам очень хочется. Замечу - код примера даже править не надо. Нужно реализовать класс расширения всего лишь.

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

Вместо многоточия может быть все что угодно, в том числе и результат вызова по HTTP или любому другому протоколу в дополнительном "кубике", если в нем есть необходимость. Различные отклонения от общей логики тоже реализуются. Обычно я делаю это свойствами конфигурационного файла, что позволяет гибко добавлять, изменять или исключать эти отклонения.

В спецификации сервлетов есть Filter, который позволяет изменять, дополнять, удалять что то во входных или возвращаемых данных. Реализованные фильтры обычно добавляются в конфигурацию приложения (web.xml). Вот вам идея как можно реализовать ваши отклонения.

Вам уже надо и ваш сервис доработать, и SQL-запросы написать. Напишите уже полный пример без балабольства, я вам ткну пальцем, где в вашем коде будет ORM.

Еще раз подчеркиваю, я Вам дал ссылку на проект в GitHub, который содержит весь код работающего примера реализации без ORM. Выделяю специально для Вас - РАБОТАЮЩЕГО ПРИМЕРА. Слово "пример", надеюсь, Вы понимаете правильно. На основе кода этого примера или на идее этого примера, можно реализовать и вашу задачу. Но это Вам нужно сделать самостоятельно.

Статусы PAID и PAYMENT_FAILED ниоткуда не приходят, но у них есть логика и эта логика работает на полученных данных или на данных, хранящихся в базе? Да. Почему эту логику нельзя повторить в SQL запросе? Не вижу проблемы написать что то подобное (написал одной строкой)

case when ... then PAID else PAYMENT_FAILED end 

Кстати, подобный SQL код можно сгенерировать и для вставки записи в БД

Не получилось сделать 7 кубиков, получилось 6. Это критично? Нет. Да, иногда может не получиться желаемого разбиения по каким либо причинам. В любом случае разбиение на кубики предпочтительнее, это решение более модифицируемо, чем все в одном.

Я уже тут объяснял почему нужно бить на кубики, не хочется повторятся. Успех такого решения в том, что у Вас или ваших коллег появляются возможность отвечать на вновь возникающие требования, порой самые неожиданные, без больших затрат и боязни что либо сломать. Не хотите бить свой код на "кубики", не бейте. Кто вам мешает.

1
23 ...

Информация

В рейтинге
Не участвует
Откуда
Нижний Новгород, Нижегородская обл., Россия
Зарегистрирован
Активность