【发布时间】:2012-02-20 13:05:53
【问题描述】:
我有很多模型类(约 1000 个)实现任意数量的 5 个接口。所以我有实现一个的类和实现四个或五个的类。
这意味着我可以对这五个接口进行任何排列。在经典模型中,我必须实现 32-5 = 27 个“元接口”,将接口“连接”到一个包中。通常,这不是问题,因为IB 通常会扩展IA 等,但就我而言,这五个接口是正交/独立的。
在我的框架代码中,我的方法需要实现任意数量的这些接口的实例。所以假设我们有类X和接口IA、IB、IC、ID和IE。 X 实现 IA、ID 和 IE。
情况变得更糟,因为其中一些接口有formal type parameters。
我现在有两个选择:
我可以定义一个接口
IADE(或者更确切地说是IPersistable_MasterSlaveCapable_XmlIdentifierProvider;下划线只是为了您的阅读乐趣)我可以将泛型类型定义为
<T extends IPersistable & IMasterSlaveCapable & IXmlIdentifierProvider>,这样可以方便地根据需要混合和匹配接口。我可以使用这样的代码:
IA a = ...; ID d = (ID)a; IE e = (IE)e,然后使用具有正确类型的局部变量来调用方法,即使这三个变量都在同一个实例上工作。或者在每隔一个方法调用中使用一次强制转换。
第一个解决方案意味着我得到了很多名称非常不可读的空接口。
第二种使用一种“临时”类型。 Oracle 的 javac 有时会在 Eclipse 正确处理时绊倒它们。
最后一个解决方案使用强制转换。纳夫说。
问题:
有没有更好的解决方案来混合任意数量的接口?
是否有任何理由避免解决方案 #2 为我提供的临时类型(Oracle 的
javac中的缺点除外)?
注意:我知道编写无法使用 Oracle 的 javac 编译的代码是有风险的。我们知道我们可以应对这种风险。
[编辑] 我在这里尝试尝试的似乎有些混乱。我的模型实例可以具有以下特征之一:
- 它们可以是“主从能力”(想想克隆)
- 它们可以有一个 XML 标识符
- 它们可能支持树操作(父/子)
- 他们可能支持修订
- 等。 (是的,模型比这更复杂)
现在我有了在树上运行的支持代码。树的扩展是具有修订的树。但我也有没有树的修订。
当我在代码中添加修订树管理器中的子项时,我知道每个实例都必须实现ITtree 和IRevisionable,但两者没有通用接口,因为它们是完全独立的问题。
但是在实现中,我需要在树的节点上调用方法:
public void addChild( T parent, T child ) {
T newRev = parent.createNewRevision();
newRev.addChild( foo );
... possibly more method calls to other interfaces ...
}
如果createNewRevision 在接口IRevisionable 中并且addChild 在接口ITree 中,我有哪些选项可以定义T?
注意:假设我有几个其他接口以类似的方式工作:有很多地方它们是独立的,但有些代码需要看到它们的混合。 IRevisionableTree 不是解决方案,而是另一个问题。
我可以为每个调用转换类型,但这似乎很笨拙。创建接口的所有排列会很无聊,而且似乎没有合理的模式来压缩巨大的接口名称。泛型提供了一个很好的出路:
public
<T extends IRevisionable & ITree>
void addChild( T parent, T child ) { ... }
这并不总是适用于 Oracle 的 javac,但它看起来紧凑且有用。任何其他选项/cmets?
【问题讨论】: