2

I'm using PubNub in Java and you essentially sub-class from SubscribeCallback to implement receiving a message. It looks like this:

public abstract class SubscribeCallback {
    public abstract void status(PubNub pubnub, PNStatus status);

    public abstract void message(PubNub pubnub, PNMessageResult message);

    public abstract void presence(PubNub pubnub, PNPresenceEventResult presence);
}

My messages are all of different classes with different payloads all inheriting from a Message class, so, my message method looks something like this:

@Override
final public void message(PubNub pubnub, PNMessageResult messageResult) {
    Message message = getMessage(messageResult);
    if (message instanceof DisplayerChanged) { 
         message((DisplayerChanged) message);
    } else if (message instanceof DisplayersChanged) {
        message((DisplayersChanged) message);
    } else if (message instanceof NewScreenshotsToRender) {
        message((NewScreenshotsToRender) message);
    } else if (message instanceof RendererChanged) {
        message((RendererChanged) message);
    } else if (message instanceof RenderersChanged) {
        message((RenderersChanged) message);
    } else if (message instanceof ScreenshotRendered) {
        message((ScreenshotRendered) message);
    } else if (message instanceof SitesChanged) {
        message((SitesChanged) message);
    } else if (message instanceof UsersChanged) {
        message((UsersChanged) message);
    } else {
        throw new RuntimeException("Received unexpected message type: " + messageResult);
    }
}

This looks horrible. Is there a better way of doing this dispatch?

The reason why I'm calling another method called message is so that different apps can inherit from this class and override message for the particular class of message it wants to handle.

Pablo Fernandez
  • 279,434
  • 135
  • 377
  • 622
  • 6
    Take a look at the Visitor pattern – Jordão Jan 05 '18 at 15:34
  • 1
    @Kayaman: how is this a duplicate of that question? That question is about lacking a cast to have the proper method called. I'm clearly doing that casting so the proper method is called. – Pablo Fernandez Jan 05 '18 at 15:42
  • Project Amber will solve this eventually! – Jacob G. Jan 05 '18 at 15:46
  • @Pablo it explains the issue and the standard way of solving double dispatch with the Visitor pattern. Were you expecting a different solution? There really isn't one. – Kayaman Jan 05 '18 at 15:52
  • @Kayaman I don't really see how these questions are related. – Arash Jan 05 '18 at 15:52
  • @Arash do you understand double dispatch? – Kayaman Jan 05 '18 at 15:54
  • I do understand double dispatch. This is a very specific design question. That question is from completely different perspective. – Arash Jan 05 '18 at 15:57
  • Looks appropriate to me. Each of your `Message` types should have a method that accepts an argument of the `SubscribeCallback` subtype and invokes the appropriate `message(..)` method, `message(this)`. – Sotirios Delimanolis Jan 05 '18 at 16:00
  • To me this looks like a textbook example. I have a hard time seeing anything special in this. – Kayaman Jan 05 '18 at 16:03

0 Answers0