Переопределение сообщения Netty.ioReceived без instanceof

В netty MessageEvent (оболочка для сообщений) имеет метод Object getMessage() для получения реального передаваемого сообщения из сети. Читая исходный код, я заметил, что они активно используют оператор instanceof для переключения между методами.

Однако, имея большое разнообразие типов сообщений, я хотел бы избежать такого метода:

public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
   if (e.getMessage() instanceof MessageType1) {
      ...
   } else if (e.getMessage() instanceof MessageType2) {
      ...
   } ... {
      ...
   } else if (e.getMessage() instanceof MessageTypeN) {
      ...
   } else {
      ctx.sendUpstream(e);
   }
}

Написание различных методов с использованием полиморфизма было бы намного лучше, например:

public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
   // MessageType implements Message
   if (e.getMessage() instanceof Message) {
      handleMessage(ctx, (Message) e.getMessage());
   } else {
      ctx.sendUpstream(e);
   }
}

void handleMessage(ChannelHandlerContext ctx, MessageType1 m) {
    ...
}

...

void handleMessage(ChannelHandlerContext ctx, MessageTypeN m) {
    ...
}

Но я не могу из-за ограничений понижения. Есть ли чистый способ сделать это или я привязан к каскаду instanceof? Я мог бы вывести логику из обработчика, используя методы .doSomething() внутри подтипов сообщений, но я хотел бы сохранить бизнес-логику внутри конвейера netty.


person matticala    schedule 22.04.2013    source источник
comment
вы можете попробовать использовать методы Class.isAssignableFrom() или Class.isInstance().   -  person kofemann    schedule 22.04.2013
comment
Однако я бы закончил еще одну длинную цепочку каскада if-else-if, я ищу что-то менее подробное. Эти два метода в любом случае являются допустимой альтернативой instanceof. Спасибо :)   -  person matticala    schedule 22.04.2013


Ответы (1)


Решено применением шаблона посетителя:

public interface Handler {
    void handleMessage(ChannelHandlerContext ctx, MessageType1 m);
    void handleMessage(ChannelHandlerContext ctx, MessageType2 m);
    ...
    void handleMessage(ChannelHandlerContext ctx, MessageTypeN m);
}

тогда:

@Sharable
public class MessageHandler extends SimpleChannelHandler implements Handler {
   ...
   @Override
   public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
     if (e.getMessage() instanceof Message) {
        Message m = (Message) e.getMessage();
        m.handleTo(ctx, this);
    } else {
        ctx.sendUpstream(e);
    }
}

@Override
public void handleMessage(ChannelHandlerContext ctx, MessageType1 m) {
    ...
}

а также

public interface Message {
   /*
    * Will be {
    *    handler.handleMessage(ctx, this);
    * }
    * everywhere.
    */
   void handleTo(ChannelHandlerContext ctx, Handler handler);
}
person matticala    schedule 22.04.2013