OOA & D / Java / Software Architecture - рекомендации по структурированию кода обработки событий, чтобы избежать сложного потока данных - PullRequest
0 голосов
/ 15 сентября 2018

Я реализовал парадигму производитель / потребитель с брокером сообщений в Spring, и мои производители используют WebSocket для извлечения и публикации данных в очереди.

Таким образом, производитель - это что-то вроде: обработчик AcmeProducer.java /AcmeWebSocketHandler.java

и с обработчиком было трудно справиться.

Во-первых, у обработчика есть два события: onOpen () onMessage ()

onOpen необходимо отправитьсообщение в веб-сокет для подписки на определенные каналы onMessage получает сообщения от WebSocket и добавляет их в очередь

onMessage имеет некоторые зависимости от AcmeProducer.java, например, ему нужно знать валютные пары для подписки, ему нужныслужба брокера сообщений, ObjectMapper (десериализатор json) и служба тестирования.

Когда сообщения принимаются из очереди, они преобразуются в формат для OrderBook.java.Каждый производитель имеет свой собственный формат OrderBook и, следовательно, свой собственный AcmeOrderBook.java.

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

Существуют ли какие-либо методы для сокращения сложного потока данных во что-то простое для отслеживания?

Как вы знаете, обработчики событий, такие как AcmeHandler.java, содержат обратные вызовы, которые вызываются из других мест системы (изреализация websocket) и, следовательно, их может быть сложно организовать.Поток данных с событиями также более запутанный, потому что когда обработчики находятся в отдельных файлах, они не могут использовать переменные, определенные в главном файле.

Если этот код не будет использовать управляемую событиями парадигму, поток данных будет легко проследить.

Наконец, есть ли лучший метод структурирования кода при использовании веб-сокетов с onOpen и onMessage?Продюсер / Потребитель - лучшее, что я могу придумать, но я не хочу разбрасывать классы Acme в разных пакетах.Например, AcmeOrderbook должен относиться к потребительскому классу, но поскольку он зависит от AcmeProducer.java и AcmeHandler.java, они часто редактируются одновременно, поэтому я собрал их вместе.

Как изависимости внутри каждого обработчика WebSocket одинаковы (только разные реализации этих одних и тех же интерфейсов). Я думаю, что должно быть введено только одно, и это будет некоторая переменная Context.Это лучшая практика?

1 Ответ

0 голосов
/ 19 ноября 2018

Я решил это с помощью диспетчера сообщений и обработчиков сообщений.

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

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

Например, внутри функции анонимного обратного вызова есть только это:

messageDispatcher.dispatchMessage(context);

Другой ключевой подход здесь - это использование контекста. MessageDispatcher - это отдельный класс(autowired).

Я разделил книгу заказов в своем каталоге внутри каждого производителя.

Ну, все требует знания всего, чтобы решить эту проблему элегантно.

Последний шаблон для решенияэто: Java EE использует аннотации для своих конечных точек и управляющих функций, таких как onOpen, onMessage и т. д. Это также хороший подход, потому что с ним обратный вызов становится невидимым, и контейнер автоматически вызывает onOpen / onMessage (используя аннотацию).

...