Pull to refresh
15
Сергей Артюх@votez

Java back-end

5
Subscribers
Send message

Ну почему же “закончить“? Наличие хорошего способа сделать что-то не означает, что все остальное — плохо.

Если не ошибаюсь, то это vertx, рассмотренный в статье. Возможно, немного модифицированный.

не думаю, что уместно переводить "sexy" как "сексуальная" в этом контексте. Более подходят для русского языка формы "модная, привлекательная".

демотивирован — за прошлую статью получил плюсов в статью и минусов в карму. Хорошо хоть на минимуме для голосования остался.
А подобная статья с базами — тема холиварная, не упомянешь какую-то деталь вроде "а вот -XXUncompressShit" или кто-то запутается в подписках реактора — у всех настроение испорчено. Слишком обширная тема, я пока остыну и, может, соберусь…
А вот GitHub, если интересно.

я тут накидал проект для теста *без веба и запросов, чтобы исключить влияние блокирующего и неблокирующего "веба" и вынес базу на внешний сервер, чтобы он не мешал бенчмарку. VertX vs R2DBC vs JDBC Postgres, все с пулом соединений. Результаты:
1) Очень сильно зависит от пула соединений. Это важно, потому что иногда можно позволить себе большой пул, а иногда нельзя. И пул все равно всегда используется. Пул для JDBC можно выбрать, а для реактивных — только по одному поддерживаемому.
2) Сильно зависит от количества конкурентных акторов.
3) Сильно зависит от того, медленные запросы в базу или быстрые.


В двух словах для старого linux jdk 11 ноута: затраты на переключение потоков невелики, пока их сотни. На тысячах начинает проявляться, если пул к базе относительно большой, но все равно довольно слабо влияет на общее время. Да, во JFR/JMC потоки на jdbc красненькие все, а в reactive все зелененькое, но толку от красок? Памяти жрет больше с потоками. Быстрее всего vertx-pg, медленнее всех r2dbc. Но на отдельных тестах все могут давать одинаковые результаты или вырываться вперед/отставать.
Ну и надо смотреть на конкретные места — маршаллинг данных, сколько прилетает в ответе данных, нужны ли транзакции, сколько запросов в транзакции. Тюнинг пула дает больше всего — там и настройки кэширования prepared statement могут быть, и прочая и прочая....

Стоит указать, что реактивщина побеждает в случае Spring. Предыдущая статья того же автора: https://technology.amis.nl/2020/03/27/performance-of-relational-database-drivers-r2dbc-vs-jdbc/ не менее интересна — там в гонке добавлен Quarkus (JDBC & R2DBC) и он в варианте JDBC бъет спринг с реактивщиной. Интересно посмотреть и на компромисы — процессор против памяти против пропускной способности.

Shell сильно зависима, но это зависимость типа "нужно для работы" — код писать "на спринге" не надо. Тут проблем не вижу, ибо для написания небольших утилит спринг не должен конфликтовать с другими библиотеками.


Насчет Spring State Machine совсем не уверен — скорее всего, можно обойтись без явного использования Spring, ведь там есть возможность строить машины программно. Однако я бы поостерегся — внутри у него наверняка много на спринг завязано, те же Timer Trigger — навскидку.

CQRS не про модель подписки, а про разделение команд на изменение от запросов на представление. То есть вполне можно через Query синхронно получить ответ из того же сервиса — это не нарушение CQRS. Паттерн в первую очередь уводит от CRUD модели, а все остальное — это бонусы от применения.

Отличная работа! Не думали оформить это в фреймворк вроде multi-agent simulation и выдать в университеты, чтобы там магистры защищались на оптимизации трафика? Задача была бы многим, я уверен, а вам — полезной. Ну и гипотезы в виртуале как минимум отбрасывать проще

Четвертый этап, который тут описан — это давно известный SOA, который провалился чуть менее, чем везде.

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

одновременно расширяет и Cat и Human?


Множественное наследование не поддерживается в Kotlin. Это если кратко. Если уйти далеко от изначальной постановки вопроса и начать играться с интерфейсами, то ответ зависит от порядка опций is в блоке when


Как будет работать эта реализация для класса SuperHuman: Human?
Если предусмотреть блок is SuperHuman ->, то он будет отрабатывать, если нет, то будет проваливаться в блок для Human. Ничего неожиданного, по-моему.

Ваш код идентичен первому листингу статьи. Не компилируется второй листинг, где переменные human и cat явно объявлены с типом суперкласса. Попробуйте что-то вроде этого :


LivingCreature human = new Human() {name = "Jorge" };

>> Не надо приводить типы, это необязательно (в супер классе обычно есть общие методы).


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


Visitor избавляет от switch и аналогов — это его прелесть. Однако это имеет смысл, когда switch/when/if читаются хуже (или по производительности проседают). Например, в Java реализация Visitor имеет смысл — он просто красив по сравнению с альтернативой. То же и в С++. В данной статье я рассматриваю только Kotlin и только для него вывод — код без Visitor более читаемый (и производительный). Я не свожу Visitor к элементарному вызову функции — я предлагаю заменить его элементарным вызовом функции.

в этом случае нет проверки на тип аргумента и возможна ошибка передачи типа visitHuman( Cat() )
А даже без ошибки программиста пришлось бы приводить тип аргумента, что является плохой практикой и классичиский Visitor ее устраняет.
Экземпляр Human может решать, мяукать или разговаривать, но речь идет о функционале вне Human, потому что с помощью Visitor мы реализовываем то, что не относится к обязанностям объекта. Нам нужны Visitor для того, чтобы оригинальный объект не инкаплулировал всю возможную логику во вселенной — смотрите часть статьи отношение Visitor и ООП

Всегда рассматривал это как побочный эффект. Но, пожалуй, тоже можно записать в плюс шаблона.
Если же использовать sealed class в when реализации, как приведено тут, то тоже будет валиться с ошибкой компиляции, как и в классическом Visitor. Конечно, не всегда sealed удобен.

Information

Rating
Does not participate
Location
Budapest, Budapest, Венгрия
Date of birth
Registered
Activity

Specialization

Бэкенд разработчик
Ведущий
Java
Scala
Java Spring Framework