Java泛型设计问题

Java泛型设计问题,java,design-patterns,generics,Java,Design Patterns,Generics,我想通过公共消息处理器将消息分派给特定的处理程序 // // Library code // abstract class Processor<M extends MessageHandler<? extends Message>> { HashMap<Class<Message>, M> handlerMap; void addHandler(M, Class<Message>); void run() {

我想通过公共消息处理器将消息分派给特定的处理程序

//
// Library code
//

abstract class Processor<M extends MessageHandler<? extends Message>> {
    HashMap<Class<Message>, M> handlerMap;
    void addHandler(M, Class<Message>);
    void run() {
        while(true) {
            ...
        }
    }
    // QUESTION - how to define this to include the fact that H extends M<T>
    //            actually im just trying to avoid the ugly cast in the client code.
    abstract <H extends MessageHandler<T>, T extends Message> void dispatch(H handler, T message);
}

class MessageHandler<T extends Message> {
}

class Message {
}

//
// Client code
//

class ServerMessage extends Message {
    ...
}

class ServerMessageHandler<T extends Message> extends MessageHandler<T> {
    ...
    void process(T msg, Object... params) {
        ...
    }
}

class ServerProcessor extends Processor<ServerMessageHandler<? extends Message>> {
    @Override
   <H extends MessageHandler<T>, T extends Message> void dispatch(H handler, T message) {
        // QUESTION - how do i get rid of this cast?
        ((ServerMessageHandler<T>)handler).process(T, ...);
   }
}
//
//库代码
//

抽象类处理器
处理器。分派
可以采用扩展
MessageHandler
的任何类型

ServerProcessor
中的方法不是一个完全重写的
处理器。dispatch
-对于不属于
ServerMessageHandler
实例且存在类强制转换异常的处理程序,它将失败(我假设
ServerMessageHandler
未扩展
MessageHandler
是一个输入错误,而不是设计错误;否则,它将无法进行所有输入,因为no
MessageHandler
是一个
ServerMessageHandler
;否则只需设置参数的类型
ServerMessageHandler

为什么您希望有一种以类型安全的方式表达本质不安全行为的方式

Processor.dispatch
的合同是
H
可以是任何
MessageHandler
T
可以是任何消息。如果H只能是处理程序的类型
Processor
的参数化为,
M
,则在定义中使用该参数:

abstract class Processor<M extends MessageHandler<? extends Message>> {
    ...
    abstract <T extends Message> void dispatch (M handler, T message);
}

但是,如果循环是从Process.run()代码中的基本事件类型的队列驱动的,那么就类型安全性而言,它不会更好,因为调用的唯一版本是
ServerDispatcher.dispatch
,调用的是
T=ServerMessage
,而强制转换隐藏在
getHandler()中
方法。安全性来自
addHandler
getHandler
的对称性,而不是来自类型变量
T
的不同绑定。将
处理器
调度程序
分离意味着只有特定的
调度程序
必须知道
T
Ser>之间的关系verMessageHandler

处理器。分派
可以采用扩展
MessageHandler
的任何类型

ServerProcessor
中的方法不是一个完全重写的
处理器。dispatch
-对于不属于
ServerMessageHandler
实例且存在类强制转换异常的处理程序,它将失败(我假设
ServerMessageHandler
未扩展
MessageHandler
是一个输入错误,而不是设计错误;否则,它将无法进行所有输入,因为no
MessageHandler
是一个
ServerMessageHandler
;否则只需设置参数的类型
ServerMessageHandler

为什么您希望有一种以类型安全的方式表达本质不安全行为的方式

Processor.dispatch
的合同是
H
可以是任何
MessageHandler
T
可以是任何消息。如果H只能是处理程序的类型
Processor
的参数化为,
M
,则在定义中使用该参数:

abstract class Processor<M extends MessageHandler<? extends Message>> {
    ...
    abstract <T extends Message> void dispatch (M handler, T message);
}

但是,如果循环是从Process.run()代码中的基本事件类型的队列驱动的,那么就类型安全性而言,它不会更好,因为调用的唯一版本是
ServerDispatcher.dispatch
,调用的是
T=ServerMessage
,而强制转换隐藏在
getHandler()中
方法。安全性来自
addHandler
getHandler
的对称性,而不是来自类型变量
T
的不同绑定。将
处理器
调度程序
分离意味着只有特定的
调度程序
必须知道
T
Ser>之间的关系verMessageHandler

我可以编写抽象的void分派(M handler,T message),但这需要在代码的客户端执行更多的强制转换,我可以编写抽象的void分派(M handler,T message)但是这需要在代码的客户端进行更多的强制转换。这可能有点不安全,但是异构类型安全容器模式给了我一点希望。我试图让公开的接口在功能上是类型安全的,而下面有一些强制转换来让它工作。我只是试图让这些强制转换我nto库端代码。修复了addHandler方法中的输入错误。还删除了ServerMessageHandler类中不必要的专门化,T应该只是扩展消息。我认为您只是把它放在了错误的位置-您不需要强制转换来调用MessageHandler的方法;并且您不能注册任何如果不是ServerMessageHandler,那么您还有什么进一步的要求?如果MessageHandler没有方法,那是为了什么?您只是对处理程序的实现进行了任意限制,但什么也得不到。您似乎有四样东西-消息、将消息推送到调度程序的处理器循环、知道ab的调度程序将额外的参数和处理程序组合起来。可以将分派器和处理器循环与C++模板组合,但是泛型只会给父类型删除。选择一个没有方法的父类型意味着在擦除之后没有什么安全的。你不会。没有办法避免演员阵容;在某些情况下,你可以使用Case.Cask,但是只需要。强制转换为T。但这并不能避免强制转换,它只会让编译器知道它不安全。如果您知道强制转换不会失败,为什么不添加一条注释并保留它呢?您最终可能会增加很多复杂性,但没有功能增益,并移动强制转换,但只要您收到任何类型的消息并选择处理程序a运行时,您将在某个地方进行强制转换。这可能有点不安全,但异构类型安全容器模式给了我一点希望。我试图使公开的接口在功能上是类型安全的,而下面有一些强制转换可以使其工作。我只是试图将这些强制转换放入库端代码中。fi修正了addHandler方法中的输入错误。还删除了不必要的字符