Мой вопрос заключается в том, чтобы реализовать различные типы поведения для разных сообщений максимально расширительно. Я знаю о шаблоне посетителя, я знаю о двойной отправке, но я не могу найти решение, которое удовлетворяет мне (не в пределах java как минимум).Двунаправленная расширяемая иерархия с Java
Моя ситуация выглядит следующим образом:
У меня есть иерархия сообщения:
и иерархия маршрутизаторы-интерфейсы, каждый из которых определяет метод маршрута для своего собственного сообщения типа:
, которые я хотел бы реализовать похожее на это:
, чтобы иметь возможность добавлять и удалять возможность направлять определенные сообщения, а также для изменения маршрутизации стратегий для определенных сообщений легко.
Проблема заключается в том, что без включения литья мое сообщение, которое я не хочу делать, я не могу выбрать соответствующую функцию для интерфейса, потому что что-то вроде
CompositeRouter comp = new AllRouter(...//new Router instances);
MessageBase msg = new DerivedMessage();
msg.process(comp);
приведет к Java выбора перегрузка <runtime message-type>.process(Router)
во время компиляции, которое во время выполнения вызывается для соответствующего объекта маршрутизатора. Поэтому я не могу выбрать правильные вызовы process() во время компиляции. Я также не могу сделать это наоборот, потому что comp.route(msg)
будет разрешен к <dynamic router-type>.route(MessageBase)
.
Я мог бы написать посетителя, который выбирает правильный метод из CompositeRouter, но для этого мне нужно было бы определить интерфейс посетителя с соответствующими методами маршрута, определенными для всех типов MessageTypes впереди, какой вид поражения цели, потому что это означает, что я должен переписать посетителя всякий раз, когда добавляю новый DerivedMessage.
Есть ли способ реализовать это так, чтобы как Message, так и Router были расширяемы или это безнадежно, учитывая текущие java-функции?
Edit 1:
Что-то я забыл упомянуть о том, что у меня есть 4 или 5 других ситуаций, которые в значительной степени так же, как Router
-hierarchy, так что я как бы хочу, чтобы избежать отражения для метода-поиска , потому что я боюсь затрат времени исполнения.
Ответ на комментарий:
@ предположения aruisdante в отношении предложения @ бота правильно. I не может переопределить, потому что я бы потерял во время выполнения тип MessageBase, если я переопределяю маршрут (MessageBase).
@aruisdante и @geceo: Я знаю, что могу это сделать - это то, что я имел в виду с «переключением» (MessageBase имеет поле MessageType) - но у меня есть 11 фактических классов сообщений и ~ 6 местоположений в код, где мне нужен , так это было бы ОГРОМНОЙ болью, а также по обслуживанию.
Возможно, я неправильно понял вашу проблему, но почему вы перегружаете методы вместо их «переопределения»? Зачем передавать сообщения как параметры? Почему бы не использовать MessageBase как зависимость в Router? – CKing
@bot Я думаю, что намерение OP состоит в том, чтобы разрешать обработку различных сообщений разными способами (перегрузка) и * также * позволять различным классам обрабатывать разные сообщения по-разному (переопределять), но не требовать от каждого класса в иерархии чтобы обеспечить все перегрузки. Проблема, с которой они сталкиваются, по существу, заключается в том, что система работает так, как предусмотрено, и сообщение, и маршрутизатор должны знать конкретный тип времени выполнения (сообщение должно знать тип маршрутизатора, маршрутизатор должен знать тип сообщения). – aruisdante
Я как-то написал несколько ограниченных ["generic function" stuff] (https://github.com/deterministic-arts/DartsJavaDispatch) для Java. Обратите внимание, что код не является ни проверенным, ни поддерживаемым, а тем более документированным или поддерживаемым. Я не рекомендую использовать его в производственных средах, но, возможно, вы можете использовать его, чтобы получить вдохновение ... – Dirk