I'm not sure if this is what you meant, but here is how polymorphism along with the double dispatch pattern would work: NaiveActor#handleLifecycleMessage will need to delegate to the event subclass, which will in turn select the appropriate method on NaiveActor.
Example of subclass of LifecycleMessage:
class ExitMessage implements LifecycleMessage {
@Override
void handle(BasicActor actor) {
actor.handleExitMessage(this);
}
}
In NaiveActor: @Override
protected void handleLifecycleMessage(LifecycleMessage m) {
m.handle(this);
}
@Override
protected void handleExitMessage(ExitMessage m) {
if (Objects.equals(m.getActor(), myBadActor) {
System.out.println("My bad actor has just died of '" + m.getCause() + "'. Restarting.");
spawnBadActor();
}
return super.handleExitMessage(m);
}
It's been my experience that many developers resort to instanceof or enum type flags because they don't believe polymorphism actually works in real world situations such as this.