Чтобы реализовать собственный пользовательский актер в Akka (привязка Java), вы расширяете базовый класс UntypedActor
. Для этого необходимо определить свой собственный onReceive(...)
метод:Akka/Java: Обработка нескольких типов сообщений внутри пользовательского актера?
@Override
public void onReceive(Object message) {
// TODO
}
Проблема в стороны, определяющей стратегию обработки сообщений, которая позволяет актерам обрабатывать множественные типы сообщений. Одна из стратегий заключалась бы в использовании отражений/типов. Проблема в том, что:
- Это заставляет нас создавать пустые «классы оболочек», которые не более чем дают семантический смысл для сообщения (см. Ниже); и
- Это свиньям параметр
message
и мешает нам быть в состоянии передать что-нибудь динамический или смысл
Пример пустого класса оболочки:
public class EmptyShellMessage { }
Затем в методе onReceive
будет выглядеть так:
@Override
public void onReceive(Class<?> message) {
if(message.isAssignableFrom(EmptyShellMessage.class)) {
// TODO
} else {
// TODO
}
}
Так что не только мы создаем иначе бесполезный класс, но так как Object message
теперь используется для кодирования того, что представляет собой класс/тип сообщения, мы не можем его использовать, чтобы содержать больше информации, особенно информацию о динамике/времени выполнения, которую может передать другой актер.
Иногда я вижу изменение этого:
@Override
public void onReceive(Object message) {
if(message instanceof FizzEvent) {
// TODO
} else {
// TODO
}
}
Но здесь мы используем instanceof
, который считается по многих быть огромный антипаттерн (только Google "InstanceOf антипаттерн «).
Тогда мы имеем перечислений:
public enum ActorMessage {
FizzEvent,
BuzzEvent,
FooEvent,
BarEvent
}
Теперь onReceive
выглядит следующим образом:
@Override
public void onReceive(ActorMessage message) {
if(message.equals(ActorMessage.FizzEvent)) {
// TODO
} else {
// TODO
}
}
Проблема здесь состоит в том, что мы можем иметь большую систему актер с сотнями или даже тысячами различных событий/сообщение типы для обработки. Это перечисление становится большим и трудным для поддержания. Он также имеет ту же проблему, что и стратегия отражения выше, где она мешает нам отправлять какую-либо динамическую информацию между участниками.
Последнее, что я могу думать о том, чтобы использовать строки:
@Override
public void onReceive(String message) {
if(message.equals("FizzEvent")) {
// TODO
} else {
// TODO
}
}
Но я ненавижу это. Период. Конец предложения.
Так что я спрашиваю: я пропустил что-то очевидное здесь, возможно, другая стратегия? Как приложения Java/Akka должны обрабатывать большое количество типов событий/сообщений и указать, какой из них они обрабатывают в методе onReceive
?
Ааа, спасибо @ Крис K (+1) - приятно знать, что я не только тот, кто чувствует себя так, неловко. Я не совсем знаком с двойной отправкой, но из моего googling кажется, что я просто напишу одну перегрузку 'onReceive' для каждого типа сообщений, с которым должен справиться мой актер. Поэтому, если я хочу, чтобы мой актер обрабатывал сообщения «Fizz» и «Buzz», у меня было бы 2 метода onReceive: (1) 'public void onReceive (Fizz fizz)' и (2) 'public void onReceive (Buzz buzz) '.Это верно? Еще раз спасибо! – smeeb
@smeeb Вам также нужен абстрактный метод для вашего сообщения, которое принимает вашего актера. В каждой конкретной реализации сообщения этот метод передает сообщение актеру. Я собирался предложить это, но мне не нравится зависимость времени компиляции, созданная из сообщений для актера. Разве вам не хотелось, чтобы ваши сообщения не знали о актере? Я думаю, этого можно избежать, объявив интерфейс протокола для вашего актора для реализации (все перегруженные методы onReceive), и тогда ваши сообщения могут зависеть от этого. – erickson
@erickson хорошо сказано. –