Aby zaimplementować własnego niestandardowego aktora w Akka (powiązanie Java), rozszerz klasę podstawową UntypedActor
. Wymaga to, aby zdefiniować własne onReceive(...)
metody:Akka/Java: Obsługa wielu typów wiadomości wewnątrz niestandardowego aktora?
@Override
public void onReceive(Object message) {
// TODO
}
Problem w zasięgu ręki jest ustalenie strategii postępowania wiadomość, która umożliwia podmiotom obsługiwać Multiple rodzaje komunikatów. Jedną ze strategii byłoby użycie refleksji/typów. Problem polega na tym, że:
- Zmusza nas do tworzenia pustych "klas powłoki", które nie robią nic więcej niż nadają znaczenie semantyczne dla wiadomości (patrz poniżej); i
- to świnie parametr
message
i pozwala nam jest w stanie przejść nic dynamiczny lub sensowne
Przykład pustej klasy powłoki:
public class EmptyShellMessage { }
Następnie w sposób onReceive
wyglądałby następująco:
@Override
public void onReceive(Class<?> message) {
if(message.isAssignableFrom(EmptyShellMessage.class)) {
// TODO
} else {
// TODO
}
}
Więc nie tylko tworzymy klasę skądinąd bezużyteczne, ale ponieważ Object message
jest obecnie używany do przekazywania informacji o klasie/typie wiadomości, nie możemy jej użyć do przechowywania jakichkolwiek informacji, szczególnie informacji dynamicznych/uruchomieniowych, które inny aktor mógłby chcieć przekazać.
Czasem widzę odmianę tego:
@Override
public void onReceive(Object message) {
if(message instanceof FizzEvent) {
// TODO
} else {
// TODO
}
}
ale tutaj używamy instanceof
która jest uważana przez wielubyć ogromny antywzorzec projektowy (tylko google "instanceof antywzorzec projektowy ").
wtedy mamy teksty stałe:
public enum ActorMessage {
FizzEvent,
BuzzEvent,
FooEvent,
BarEvent
}
Teraz onReceive
wygląda następująco:
@Override
public void onReceive(ActorMessage message) {
if(message.equals(ActorMessage.FizzEvent)) {
// TODO
} else {
// TODO
}
}
Problem polega na tym, że możemy mieć duży system aktor z setek lub nawet tysięcy różnych zdarzeń/wiadomości typy do obsługi. To wyliczenie staje się duże i trudne do utrzymania. Ma również ten sam problem, co strategia odbicia, powyżej której uniemożliwia nam wysyłanie dynamicznych informacji między aktorami.
Ostatnią rzeczą mogę myśleć jest użycie ciągi:
@Override
public void onReceive(String message) {
if(message.equals("FizzEvent")) {
// TODO
} else {
// TODO
}
}
Ale nienawidzę tego. Kropka. Koniec zdania.
Więc pytam: czy brakuje tu czegoś oczywistego, może innej strategii? W jaki sposób aplikacje Java/Akka powinny obsługiwać dużą liczbę typów zdarzeń/wiadomości i określić, które z nich obsługują w metodzie onReceive
?
Ahh, dzięki @Chris K (+1) - miło wiedzieć, że nie jestem tylko ten, kto tak czuje, jest niezręczny. Nie jestem do końca obeznany z podwójną wysyłką, ale z mojego wyszukiwania google wynika, że po prostu napisałbym jeden przeciążenie onReceive dla każdego typu wiadomości, którą mój aktor musi obsługiwać. Więc jeśli chcę, aby mój aktor obsługiwał wiadomości "Fizz" i "Buzza", będę miał 2 metody "onReceive": (1) 'public void onReceive (Fizz fizz)' and (2) 'public void onReceive (Buzz buzz) '.Czy to jest poprawne? Dzięki jeszcze raz! – smeeb
@smeeb Potrzebna jest również abstrakcyjna metoda na wiadomości, która akceptuje aktora. W każdej konkretnej implementacji wiadomości, ta metoda przekazuje wiadomość do aktora. Chciałem to zasugerować, ale nie podoba mi się zależność od czasu kompilacji, którą tworzy z wiadomości do aktora. Czy nie chciałbyś, aby twoje wiadomości były nieświadome aktora? Sądzę, że można tego uniknąć, deklarując interfejs protokołu dla twojego aktora do implementacji (wszystkie przeciążone metody onReceive), a wtedy twoje wiadomości mogą na tym polegać. – erickson
@erickson dobrze powiedział. –