Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 不确定应用程序的设计方法_Java - Fatal编程技术网

Java 不确定应用程序的设计方法

Java 不确定应用程序的设计方法,java,Java,我正在尝试用Java创建一个应用程序,它允许从小种子图生成大的出处图,但我在找出设计类的最佳方法时遇到了一点困难 首先,起源基本上有一个图结构、节点和边。我创建了一个Java库,它充当了源数据模型到Java对象的映射。这使我能够从源模型中提取特定于应用程序的信息 我的班级结构有点像这样: 图(包含节点集和边集) 抽象节点(目前仅为字符串名称) 代理人 活动 实体 节点的其他子类 抽象边 世代 联想 边的其他子类 现在,我想做的是在节点和边上提供权重,作为乘数/饱和度级别。我有几种方法

我正在尝试用Java创建一个应用程序,它允许从小种子图生成大的出处图,但我在找出设计类的最佳方法时遇到了一点困难

首先,起源基本上有一个图结构、节点和边。我创建了一个Java库,它充当了源数据模型到Java对象的映射。这使我能够从源模型中提取特定于应用程序的信息

我的班级结构有点像这样:

  • 图(包含节点集和边集)
  • 抽象节点(目前仅为字符串名称)
    • 代理人
    • 活动
    • 实体
    • 节点的其他子类
  • 抽象边
    • 世代
    • 联想
    • 边的其他子类
现在,我想做的是在节点和边上提供权重,作为乘数/饱和度级别。我有几种方法可以使用这个库来实现这个目标,但我不清楚从开发和可维护性的角度来看什么是最好的

首先,我用一些简单的方法定义了一个可称重的接口,比如获取和设置最小和最大权重

现在,我可以扩展每个子类节点,例如

class WeighableAgent extends Agent implements Weighable
但这需要为每种类型的节点提供一个扩展类,并要求我在每一个级别实现可称重接口

或者,我可以提供一个mixin,但它仍然依赖于我在每个子类中实现相同的功能

或者,我可以有一个基于代理的类,但这仍然需要我在每个组合类中实现可加权

或者,我可以单独在Node类上编写,例如

class WeighableNode implements Weighable {

    private Node node;

    public WeighableNode(Node node) {
        this.node = node;
    }

    etc etc...
这将允许我只在一个地方进行称重。但是,使用WeighableNode时,我会丢失一些关于具体类类型的重要信息,我看到的唯一解决方法是提供一个方法:

Node getNode();
根据德米特定律,我很担心。此外,此WeighableNode将由PresentationNode组成,以帮助Swing,这意味着我将链接调用,例如:

presentationNode.getWeighableNode().getNode() instanceof Agent
这看起来很不愉快

我刚刚想到的最后一个解决方案是在上面的节点上进行组合,然后使用WeighableAgent等扩展WeighableNode。这意味着我不需要每次都重新实现WeighableNode,如果我知道我已经实现了的话

instanceof WeighableAgent
那么包装的节点就是一个代理


我知道这很长,但我希望有经验的开发人员能够很快看到正确的设计实践。

太糟糕了,Java既没有真正的混合,也没有多重继承

通用包装器 我想我会使用
WeighableNode
作为通用包装类型。这样,所有需要特定类型节点的地方都可以清楚地说明这一事实。它的
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);
        }
    }
}
这将实现和接口分离开来,如果需要的话,您可以在以后自由地进行更改。基本的
节点
实现将知道如何转换自身,同时处理派生类。
NodeWrapper
将使用组合添加转换。您可以将其用作
WeighableNode
presentationNode
的基类

脂肪界面
您可以在
节点
本身中实现称重功能,并将
称重节点
用作标记接口,或者根本不使用。这不是最好的解决方案,但有助于减少类的数量,并且除了额外数据消耗的内存位之外,不会造成任何实际伤害。到目前为止,其他方案所需的间接寻址级别可能会超过内存需求。

+1尽管这是一篇很长的文章,但感谢您清楚地揭示了您的问题。您好,非常感谢您的回答。非常感谢。我会考虑一下,尝试一下实施,然后回复你。关于Fat接口,我想继续在节点外称重,因为我觉得库应该只封装PROV-DM,因此应该可以在其他不关心称重的地方恢复,例如,当生成最终图形时,将没有这种重量概念,或者在其他项目中。
presentationNode.getNode(Agent.class)