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
是一个输入错误,而不是设计错误;否则,它将无法进行所有输入,因为noMessageHandler
是一个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
是一个输入错误,而不是设计错误;否则,它将无法进行所有输入,因为noMessageHandler
是一个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方法中的输入错误。还删除了不必要的字符