2013-04-22 1 views
0

В netty MessageEvent (оболочка для сообщений) имеет метод Object getMessage(), чтобы получить реальное переданное сообщение из сети. Читая источник, я заметил, что они активно используют оператор instanceof для переключения между методами.Netty.io messageReceived переопределить без 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 cascade? Я мог бы вывести логику из обработчика, используя методы .doSomething() внутри подтипов сообщений, но я хотел бы сохранить бизнес-логику внутри конвейера netty.

+0

вы можете попробовать использовать Class.isAssignableFrom() или Class.isInstance() методы. – kofemann

+0

Я бы, однако, попал в другую длинную цепочку if-else-if cascade, я ищу что-то менее подробное. Эти два метода в любом случае являются действительной альтернативой instanceof. Спасибо :) – matticala

ответ

0

решена применением Visitor Pattern:

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); 
}