使用Java的双向可扩展层次结构

mid*_*dor 6 java oop double-dispatch

我的问题是以尽可能可扩展的方式为不同的消息实现不同的行为.我知道访问者模式,我知道双重调度,但我似乎无法找到一个解决方案,这让我感到困惑(至少不在java的范围内).

我的情况如下:

我有一个消息层次结构:

消息层次结构

路由器接口的层次结构,每个都定义了自己的消息类型的路由方法:

路由器接口层次结构

我想实现类似于此:

履行

能够添加和删除路由某些消息的功能,以及轻松更改某些消息的路由策略.

问题是,没有开关转换我的消息,我不想做,我不能选择相应的功能的界面,因为像

CompositeRouter comp = new AllRouter(...//new Router instances);
MessageBase msg = new DerivedMessage();
msg.process(comp);
Run Code Online (Sandbox Code Playgroud)

会导致java选择重载 <runtime message-type>.process(Router)

在编译时,在运行时,为相应的路由器对象调用它.所以我似乎无法在编译时选择正确的process()调用.我也不能反过来这样做,因为comp.route(msg)

将被解决<dynamic router-type>.route(MessageBase).

我可以写一个游客,它选择从CompositeRouter的正确方法,但为此我必须定义为所有的MessageTypes定义了前面的各路线的方法,哪一种失败的目的访问者接口,因为这意味着我每当我添加一个新的DerivedMessage时,都必须重写访问者.

有没有办法实现这一点,以便消息和路由器都是可扩展的,或者在给定当前的java特性的情况下它是否没有希望?

编辑1:

我忘记提到的是我有4或5个其他情况,它们与Router-hierarchy 几乎相同,所以我有点想避免使用Reflection进行方法查找,因为我害怕运行时成本.

回复评论:

  1. @ aruisdante关于@ bot的建议的假设是正确的.我不能覆盖,因为如果我覆盖路由(MessageBase),我将松开运行时类型的MessageBase.

  2. @aruisdante和@geceo:我知道我可以这样做 - 这就是我对"switch-casting"的意思(MessageBase有一个MessageType字段) - 但我有11个实际的消息类和~6个位置代码我需要它,这将是一个巨大的痛苦实施 - 以及维护明智.

Jon*_*mer 1

在 Scala(另一种 JVM 语言)中,这听起来像是类型类的用例:

http://danielwestheide.com/blog/2013/02/06/the-neophytes-guide-to-scala-part-12-type-classes.html

这在 Java 中是不可能的,尽管如果你用 google 搜索“Java 类型类”,可以找到一些实验性库。