[英]Unsure how approach design of application
我正在尝试用Java创建一个应用程序,它允许从小种子图生成大型的Provenance图,但是我在设计我的类的最佳方法时遇到了一些麻烦。
首先,Provenance基本上有一个图形结构,节点和边缘。 我创建了一个Java库,它充当了Provenance Data Model到Java Objects的映射。 这允许我从Provenance模型中抽象出我的应用程序特定信息。
我的类结构看起来有点像这样:
现在,我想要做的是在节点和边缘上提供加权,作为乘数/饱和度。 我可以通过两种方式使用该库来实现这一目标,但我不清楚从开发和可维护性角度来看哪些是最好的。
首先,我使用一些简单的方法定义了一个Weighable接口,例如get和set最小和最大权重。
现在,我可以扩展每个子类节点,例如
class WeighableAgent extends Agent implements Weighable
但是,这需要为每种类型的节点提供扩展类,并要求我在每个级别实现Weighable接口。
或者,我可以提供一个mixin,但它仍然依赖于我在每个子类中实现相同的功能。
或者,我可以有一个在Agent上编写的类,但是仍然需要我在每个组合类中实现Weighable。
或者,我可以仅仅在Node类上编写,例如
class WeighableNode implements Weighable {
private Node node;
public WeighableNode(Node node) {
this.node = node;
}
etc etc...
这将允许我只在一个地方实现Weighable。 但是,我从使用WeighableNode的任何东西中丢失了一些关于具体类类型的重要信息,我看到的唯一方法就是提供一个方法:
Node getNode();
由于德米特定律,我对此感到担忧。 此外,这个WeighableNode将由PresentationNode组成,以帮助Swing,这意味着我最终将链接调用,例如:
presentationNode.getWeighableNode().getNode() instanceof Agent
这看起来很不愉快。
我刚想到的最后一个解决方案就是如上所述构建Node,然后使用WeighableAgent等扩展WeighableNode等。这意味着每次我都不需要重新实现Weighable,如果我知道我有
instanceof WeighableAgent
然后包装的节点是一个代理。
我很欣赏这很长,但我希望有经验的开发人员能够很快看到正确的设计实践。
太糟糕的Java既没有真正的混合也没有多重继承......
我想我会使用WeighableNode<NodeType extends Node>
作为通用包装器类型。 这样,所有需要特定类型节点的地方都可以清楚地说明这一事实。 它的getNode
方法可以返回正确的类。 而且你不会在这个地方结束太多的课程。
即使您不使用上述方法,以下习语可能会很有趣:
class Node {
public T asNode(Class<T extends Node> clazz) {
return clazz.cast(this);
}
}
class NodeWrapper<N extends Node> {
private N realNode;
public T asNode(Class<T extends Node> clazz) {
try {
return super.asNode(clazz);
}
catch (ClassCastException e) {
return realNode.asNode(clazz);
}
}
}
如果您愿意,可以将上面的内容更改为返回null
而不是抛出异常。 这个想法是调用代码不必担心如何将节点转换为各种类型。 你可以简单地写一下
presentationNode.getNode(Agent.class)
这将实现与界面分开,如果需要,您可以在以后更改自由。 基本的Node
实现将知道如何转换自身,处理派生类。 NodeWrapper
将使用合成添加转换。 您可以将其用作WeighableNode
和presentationNode
的基类。
您可以在Node
本身中实现称重,并将WeighedNode
用作标记接口,或者根本不使用。 这不是最好的解决方案,但会帮助保持你的课程数量,并且不应该做任何真正的伤害,除了额外数据消耗的内存。 到目前为止,其他方案所需的间接级别可能会超过内存需求。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.