[google/guava]请将图表和图表构建器公开且非最终版本

2018-06-25 934 views
5

我想扩展一个图形类,以便用更短的、更适合我的使用的名称来替换它生成的巨大类型名称。当构建图表时,它的类型名称类似于,MutableValueGraph<SourceElement, SourceRelationship>而我想用一个名为 ... 的类来扩展它SourceGraph,好多了!图形生成器类不允许更改来构建自定义图形,除非您乐意重新发明轮子,因此复制粘贴代码只是为了使用较短的名称或在各处使用较大的名称。如果这些类是可扩展的,我的用例将非常简单。

如果有充分的理由不这样做,我不知道,但很想听听。

回答

4

扩展类来提供typedef类似的功能通常效果并不好:一旦您调用类似的方法transitiveClosure,您就会得到一个Graph不再是正确类型的方法。

您可以考虑创建一个SourceGraph包含 实例的类型MutableValueGraph<SourceElement, SourceRelationship>,但是当然,您要么需要复制您感兴趣的方法,要么引用sourceGraph.theActualGraph.someMethod()

(也就是说,MutableValueGraph是一个接口,所以我认为如果您愿意,您可以创建它的子类型。这对像 之类的类型没有帮助ImmutableGraph,但我们要特别小心让任何人对它们进行子类化,因为人们可能会破坏不变性保证。)

2

旁注:一般来说,人们应该使用类型的唯一时间Mutable是当他们修改图形或返回调用者期望可修改的图形时。否则你应该(在这种情况下)使用ValueGraph<...>.

ValueGraph当然,它的兄弟姐妹也是您可以创建其子类型的接口。)

3

公平地说,调用传递闭包无论如何都不尊重原始图类,即使它是番石榴图类。是的,转发或复制粘贴似乎是唯一的选择,但我有点希望避免它们。我想我会选择 jgrapht,因为它更开放,尽管它​​不那么干净。无论如何,感谢您的快速回复,非常感谢!

6

不确定你所说的transitiveClosure“不尊重原始图形类”是什么意思。它必须创建一个新的图实例,以避免改变其输入。您希望它如何工作,为什么您希望它返回除 之外的特定类型Graph<N>

无论如何,我们已经考虑完善并公开Forwarding*common.graph 目前在内部使用的类,例如Graph.transpose().如果这会让您的生活更轻松,请为此提出问题。谢谢。

1

我也很想知道“transitiveClosure 不尊重原始图形类”是什么意思。您的意思是您希望返回的图表与原始图表具有完全相同的类型吗?或者你还有别的意思吗?

0

我对该方法没有任何期望,只是提到它,因为它是作为不允许扩展 Graph 子类的原因而提出的,而其他子类也是如此。我并不是想改变你做事的方式!这实际上只是为了让我时不时地输入六个单词,哈哈 FWIW 有几种方法可以返回相同的类型,但我不确定它们是否会添加足够的价值,其中一些是我的想法: () 调用 graph.getClass().newInstance() 添加类型化的 createBlankGraph() 方法 在创建空白图等的每个图中存储供应商。

5

我应该为开始这部分讨论负责:)我可能夸大了事情。我知道过去当人们(包括我)尝试像这样的“typedef”时我见过问题,但已经有一段时间了,我不太记得细节了。因此,虽然我仍然不会推荐该模式,但它可能适合您的情况。

(我设法挖掘出关于一般模式的伪 typedef 反模式。)

7

@NateUniAccount 感谢您提供额外的背景信息。一些快速回复供将来参考:

  • clone()似乎不太合适,因为这意味着“创建此对象的副本”而不是“创建此对象类型的新实例”。
  • graph.getClass().newInstance()从概念上讲会更合适,但我不喜欢使用反射,除非绝对必要。
  • 我不确定您建议在库createBlankGraph()中添加“类型化”方法common.graph。当然,这当然是您可以为自己创建的东西(在我看来,这可能是最好的解决方案)。

对于那些可能正在阅读此线程并想知道构建与现有图相同类型的图实例的最佳方法的人来说common.graph,就是这样:

Graph<N> newGraph = GraphBuilder.from(existingGraph).build();

我们可能会在某个时候builder()向图形接口添加一个方法,以提供替代的(也许更简单的?)方法来执行此操作:

Graph<N> newGraph = existingGraph.builder().build();

(我不会具体评论“typedef”的事情,因为我认为 @cpovirk 已经涵盖了这一点。)

1

@jrtom

我不确定你建议添加什么“类型createBlankGraph()

我敢打赌,他的意思是一个实例方法返回一个新的空实例(就像graph.getClass().newInstance(),但以您喜欢的任何方式实现)。无论如何,鉴于GraphBuilder,它是不需要的。

我们可能会在某个时候向图形接口添加一个 builder() 方法,以提供另一种(也许更简单?)的方法:

恕我直言,它更容易,但也许toBuilder()会是一个更好的名称,因为builder()通常是静态方法(有些类可能需要两者)。

2

与 相比,拥有一个返回新的空实例的实例方法的好处GraphBuilder是,您可以让它返回您的特定子类型Graph(或其他类型);最初的担忧是,因为GraphBuilderfinal无法创建自己的子类来返回自己的Graph子类型。

我同意这toBuilder()是该假设方法的更好名称。

1

该死……我想,我应该多睡一会儿。 ;)