使用多种接口的最佳方法是什么?

Aar*_*lla 10 java generics interface

我有一个情况,我有很多模型类(~1000)实现任意数量的5个接口.所以我有一些实现一个的类和一个实现四个或五个的类.

这意味着我可以对这五个接口进行任何排列.在经典模型中,我必须实现32-5 = 27"元接口",它们"捆绑"接口中的接口.通常,这不是问题,因为IB通常是扩展IA等,但在我的情况下,五个接口是正交/独立的.

在我的框架代码中,我有一些方法需要实现任意数量的接口的实例.所以,让我们假设我们有类X和接口IA,IB,IC,IDIE.X实现IA,IDIE.

情况变得更糟,因为其中一些接口具有正式的类型参数.

我现在有两个选择:

  1. 我可以定义一个界面IADE(或者更确切地说IPersistable_MasterSlaveCapable_XmlIdentifierProvider;下划线只是为了您的阅读乐趣)

  2. 我可以定义一个泛型类型,<T extends IPersistable & IMasterSlaveCapable & IXmlIdentifierProvider>这将为我提供一个方便的方法来混合和匹配接口,因为我需要它们.

  3. 我可以使用这样的代码:IA a = ...; ID d = (ID)a; IE e = (IE)e然后使用具有正确类型的局部变量来调用方法,即使所有三个都在同一个实例上工作.或者在每个第二个方法调用中使用强制转换.

第一个解决方案意味着我得到了很多名称非常难以理解的空接口.

第二种使用一种"临时"打字.javac当Eclipse正确的时候,Oracle 有时会绊倒他们.

最后一个解决方案使用演员表.努夫说.

问题:

  1. 是否有更好的解决方案来混合任意数量的接口?

  2. 有没有理由避免解决#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 ...
}
Run Code Online (Sandbox Code Playgroud)

如果createNewRevision在界面中IRevisionable并且addChild在界面中ITree,我可以选择定义T什么?

注意:假设我有几个其他接口以类似的方式工作:有许多地方它们是独立的,但有些代码需要看到它们的混合.IRevisionableTree不是解决方案,而是另一个问题.

我可以为每个电话投出类型,但这看起来很笨拙.创建接口的所有排列都很无聊,似乎没有合理的模式来压缩巨大的接口名称.泛型提供了一个很好的出路:

public
<T extends IRevisionable & ITree>
void addChild( T parent, T child ) { ... }
Run Code Online (Sandbox Code Playgroud)

这并不总是适用于Oracle,javac但它似乎紧凑而有用.还有其他选择/评论吗?

Joo*_*gen 3

松散耦合的功能可能会很有趣。这里有一个例子。这是一种完全不同的方法;解耦事物而不是打字。基本上接口是隐藏的,作为委托字段实现。

IA ia = x.lookupCapability(IA.class);
if (ia != null) {
    ia.a();
}
Run Code Online (Sandbox Code Playgroud)

它适合这里,就像许多接口一样,解耦的愿望会增加,并且您可以更轻松地组合相互依赖的接口的情况 ( if (ia != null && ib != null) ...)。