Java 中的多态调度
在下文中,我希望 EventHandler 以一种方式处理 EventA,以另一种方式处理 EventB,以及以另一种方式处理任何其他事件(EventC、EventD)。 EventReceiver 仅接收对 Event 的引用并调用 EventHandler.handle()。当然,总是被调用的版本是EventHandler.handle(Event event)。
如果不使用instanceOf,是否有一种方法可以多态地分派(可能通过EventHandler或泛型中的另一个方法)到适当的句柄方法?
class EventA extends Event {
}
class EventB extends Event {
}
class EventC extends Event {
}
class EventD extends Event {
}
class EventHandler {
void handle(EventA event) {
System.out.println("Handling EventA");
}
void handle(EventB event) {
System.out.println("Handling EventB");
}
void handle(Event event) {
System.out.println("Handling Event");
}
}
class EventReceiver {
private EventHandler handler;
void receive(Event event) {
handler.handle(event);
}
}
In the following, I want EventHandler to handle EventA one way, EventB another way, and any other Events (EventC, EventD) yet another way. EventReceiver receives only a reference to an Event and calls EventHandler.handle(). The version that always gets called, of course, is EventHandler.handle(Event event).
Without using instanceOf, is there a way to polymorphically dispatch (perhaps via another method in EventHandler or generics) to the appropriate handle method?
class EventA extends Event {
}
class EventB extends Event {
}
class EventC extends Event {
}
class EventD extends Event {
}
class EventHandler {
void handle(EventA event) {
System.out.println("Handling EventA");
}
void handle(EventB event) {
System.out.println("Handling EventB");
}
void handle(Event event) {
System.out.println("Handling Event");
}
}
class EventReceiver {
private EventHandler handler;
void receive(Event event) {
handler.handle(event);
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
听起来像是应用访问者模式(的变体)的案例。 (在主流的面向对象语言,如C++、C#和Java中,方法是单分派,即一次只能在一种类型上多态。访问者允许实现双分派 >.)
但是,这要求您也能够修改
Event
类,并创建从Event
到EventHandler(的基本接口)的依赖关系
。Sounds like a case for applying (a variant of) the Visitor pattern. (In mainstream OO languages such as C++, C# and Java, methods are single dispatch, i.e. can only be polymorphic on one type at a time. Visitor allows one to implement double dispatch.)
This however requires that you be able to modify the
Event
classes as well, and creates a dependency fromEvent
s to (a base interface of)EventHandler
.这是 double-dispatch 的一个用例,不(人们可能确实知道这是要么称为访客)?我将仅针对 EventA 实现您的示例
This is a use case for double-dispatch, no (which as one may indeed know is either called Visitor) ? I'll implement your example for EventA only
Java 仅对调用方法的对象进行多态分派。这意味着,获得真正多态性的唯一方法是将
handle()
方法放入Event
接口本身。实际上,我想说这是总体上更好、更面向对象的解决方案,因为对数据对象进行操作的“处理程序”是相当程序化的。任何其他解决方案(例如在类上键入的处理程序对象的映射)都将更加复杂且灵活性较差,尤其是在继承方面。
Java only has polymorphic dispatch on the object a method is invoked on. That means, the only way to get real polymorphism is to put the
handle()
method into theEvent
interface itself. I'd actually say that is the overall better and more OO solution, since a "handler" that operates on data objects is rather procedural.Any other solution (like a map of handler objects keyed on the class) is going to be more complex and less flexible, especially concerning inheritance.
您可以使用映射并将事件类型映射到事件处理程序。
You could use a Map and map event types to event handlers.
我知道如何通过一些预处理来做到这一点。使用如下内容:
然后使用映射来组织处理程序
当需要处理事件时,只需从映射中检索处理程序即可。如果 Class.equals() 和 Class.hashCode() 不能按您想要的方式工作,那么您将需要一个包装器来获得您想要的行为。
I know how you can do it with some pre-processing. Use something like this:
Then use a map to organize your handlers
When an event needs to be handled just retrieve the handlers from the map. If Class.equals() and Class.hashCode() doesn't work how you want then you'll need a wrapper to get the behavior you want.