在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 级联相关联? 我可以使用Message子类型中的.doSomething()方法将逻辑输出到Handler,但我想将业务逻辑保留在netty管道中。
答案 0 :(得分:0)
解决了申请访客模式:
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);
}