在这种情况下如何避免重复代码?

时间:2013-04-17 19:03:22

标签: java oop inheritance interface

我的项目是关于在java中实现hyperGraph

我的hyperGraph包含各种类型的hyperEdge,具体取决于我所拥有的顶点类型

顶点类型:图像,标签......

HyperEdge =同质(关联相同类型的顶点)/异构(关联不同类型的顶点)

同构HyperEdge =图像图像HyperEdge / Tag-tag hyperEdge

这是一个快速绘制的UML图

enter image description here

enter image description here 这是我的代码

public interface HomogenousHyperedge< T extends Vertex<L>, L> extends Hyperedge {

   public abstract List<T> searchNearstNeighborsVertex(
      Hypergraph hypergraph, T vertex);
}


public class ImageImageHyperedge implements
   HomogenousHyperedge<ImageVertex, Map<String,Instance>> {

   @Override
   public List<ImageVertex> searchNearstNeighborsVertex(Hypergraph hypergraph,
        ImageVertex vertex) {
      return null;
   }
}

问题出在ImageImageHyperEdge类中我应该知道基于它的特征是什么类型我将搜索ImageVertex最近的邻居 我不能将它传递给超级接口的抽象方法,因为TagTagHyperEdge类不需要它

如果我用{featureOneHyperEdge类,... featureFiveHyperEdge类}替换ImageImageHyperEdge类(我知道其中的特征类型) 它将是一个重复的代码,因为它是相同的最近邻搜索算法


特征=图像的低级特征(例如颜色直方图)
我有5种低级功能
我将使用每一个来搜索当前图像的最近邻居
所有功能都存储在一个简单的文本文件中 相同的算法用于搜索最近的邻居
每次只更改文件

3 个答案:

答案 0 :(得分:1)

你的UML设计不够好。跳过丑陋的&amp;难以阅读的'造型',向我们展示'Vertex'以及'Edge'和关联图;不是你的(可能过于复杂)继承的想法。

您的API,设计&amp;根本问题并不是很清楚。 'Hyperedge'类可以代表Edge的单个实例,并将其两端相关联;或者它们(如果更好地命名)表示边缘类型,并从指定的端点参数全局搜索图形。

这些是完全不同的设计,在你弄清楚上述情况之前,你的问题毫无意义。

无论哪种方式,Edge.search()都没有正确的签名。 VS和VE是起始和结束顶点类型,而TE是边缘类型,它应该是:

public class EdgeType {
    public List<EV> getEndpoints (SV startVertex);
}

public class Vertex {
    public List<TE> Vertex.getEdges();
}
public class Edge {
    public EV Edge.getEndpoint();
}

最近邻算法应使用泛型类型实现,然后由具体类根据需要调用(具有精确类型签名)。

顺便提一下,当你提到“最近邻居”时;也不清楚“最近邻居”是指直接连接的顶点,这是微不足道的,或者找到最近的距离(如何测量距离?你没有指定)指定类型的顶点。 / p>

无论哪种方式,实用程序&amp;正确性/需要实现'边缘'的子类型似乎不清楚。许多图算法发现顶点/节点很有趣并且这些是子类型,但我不太了解通向这些的边缘的子类型(或子类型的效用)。

最后提示:放弃复杂的命名,KISS。 'Vertex'和'Edge'将帮助您获得清晰,简单,易于理解的信息。正确的设计。 之后为保存额外的字数。


回应Nawara的进一步信息:

然后它是你已经建模的EdgeType,当问'最近邻居'时你应该选择一个Start Vertex&amp;返回Edge(s) - 如果需要距离度量 - 或顶点。

“图形”的引用可能隐含在Vertex参数中。

至于你的EdgeType继承heirarchy:subtypes&amp;应该定义继承遵循行为特征,而不是它们引用的泛型类型(Vertex类型)。 OO类层次设计的原则是模拟,而不是

在这方面你可能有一个KnnDistanceEdgeType&amp; FlickrDistanceEdgeType类,作为祖先,或者,如果没有其他方法行为需要不同,则作为实际的实现类。他们正在搜索的要素类型/类可以设置为属性 - 具有属性&amp;通用化不同,回答不同的顶点类型。

例如

IMAGE_IMAGE_EDGES = new KnnDistanceEdgeType<ImageVertex,ImageVertex>( ImageVertex.class, ImageVertex.class);
TAG_TAG_EDGES = new FlickrDistanceEdgeType<TagVertex,TagVertex>( TagVertex.class, TagVertex.class);
ANY_EDGES = new KnnDistanceEdgeType<Vertex,Vertex>( Vertex.class, Vertex.class);

如果在EdgeType中还有很多其他行为(我们没有定义任何行为,也无法想象),您可以将KNN和Flickr距离算法移到单独的类中。可能没必要。

记住:在OO中,行为的子类,而不是存在。并给我+1票!

答案 1 :(得分:0)

根据您撰写的有关“功能”的内容,我会说这适合作为ImageImageHyperEdge类中的字段。您可以使用将定义它的各种成员创建FeatureType类。

public class ImageImageHyperedge implements
   HomogenousHyperedge<ImageVertex, Map<String,Instance>> {

   private FeatureType featureType;

   @Override
   public List<ImageVertex> searchNearstNeighborsVertex(Hypergraph hypergraph,
        ImageVertex vertex) {
      return null;
   }
}

答案 2 :(得分:0)

尝试这样的事情?

public abstract class BaseFeatureHyperEdge {

    @Override
   public List<ImageVertex> searchNearstNeighborsVertex(Hypergraph hypergraph,
        ImageVertex vertex) {   
      // implement nearest neighbor search algorithm
      // and call getFeatureType where you need it.
      // This will allow you to have the search algorithm only in one place. 
      //But make the search based on the feature type;
   }

   protected FeatureType getFeatureType();
}

public class FeatureOneHyperEdge extends BaseFeatureHyperEdge{

    @Override
    protected FeatureType getFeatureType() {
        return new FeatureTypeOne();
    }
}


public class FeatureTwoHyperEdge extends BaseFeatureHyperEdge{

    @Override
    protected FeatureType getFeatureType() {
        return new FeatureTypeTwo();
    }
}

也许你可以试试Template Method Pattern