我的问题是以尽可能可扩展的方式为不同的消息实现不同的行为。我知道访问者模式,我知道双重调度,但我似乎无法找到一个让我满意的解决方案(至少不在 java 的范围内)。
我的情况如下:
我有一个消息层次结构:
以及路由器接口的层次结构,每个接口都为自己的消息类型定义了一个路由方法:
我想实现类似于此:
能够添加和删除路由某些消息的能力,以及轻松更改某些消息的路由策略。
问题是,如果不切换我不想做的消息,我无法为界面选择相应的功能,因为类似
CompositeRouter comp = new AllRouter(...//new Router instances);
MessageBase msg = new DerivedMessage();
msg.process(comp);
会导致java选择重载<runtime message-type>.process(Router)
在编译时,在运行时为相应的路由器对象调用。所以我似乎无法在编译时选择正确的 process() 调用。我也不能反过来做,因为comp.route(msg)
将解决<dynamic router-type>.route(MessageBase)
。
我可以编写一个访问者,它从 CompositeRouter 中选择正确的方法,但因此我必须使用预先为所有 MessageTypes 定义的相应路由方法来定义访问者接口,这违背了目的,因为这意味着我每当我添加新的 DerivedMessage 时,都必须重写访问者。
有没有办法实现这一点,使得消息和路由器都是可扩展的,或者考虑到当前的 java 特性,它是没有希望的?
编辑1:
我忘了提到的是我有 4 或 5 种其他情况,它们与Router
-hierarchy 几乎相同,所以我有点想避免反射进行方法查找,因为我害怕运行时成本。
回复评论:
@aruisdante 关于@bot 建议的假设是正确的。我无法覆盖,因为如果我覆盖路由(MessageBase),我会丢失 MessageBase 的运行时类型。
@aruisdante 和@geceo:我知道我可以做到这一点——这就是我所说的“切换转换”(MessageBase 有一个 MessageType 字段)——但我有 11 个实际消息类和大约 6 个我需要的代码位置,所以这将是一个巨大的痛苦实施 - 以及维护方面。