Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid the duplication of code in this case?

My project is about implementing an hyperGraph in java

My hyperGraph contain various type of hyperEdge depending on vertex type that I have

Vertex Type:Image , tags ...

HyperEdge =Homogeneous(relate vertex of same type )/Heterogeneous(relate vertex of different type)

Homogeneous HyperEdge= Image-image HyperEdge/Tag-tag hyperEdge

This is a quickly draw UML diagram

enter image description here

enter image description here this is my code

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;
   }
}

the problem is in the ImageImageHyperEdge class I should to know what is the type of feature based on it I will search the ImageVertex nearest neighbors I can't pass it into the abstract method of the super Interface because TagTagHyperEdge class don't need it

and if I replace ImageImageHyperEdge class by {featureOneHyperEdge class ,...featureFiveHyperEdge class } (in which I know the feature type) it will be a duplication of code as it is the same nearest neighbors search algorithm


feature= low level feature of an image (color histogram for example)
I have 5 type of low level feature
I will use each one to search the nearest neighbors of my current image
All feature are stocked in a simple textual file
the same algorithm is used to search the nearest neighbors
only the file is changed every time

like image 688
nawara Avatar asked Apr 17 '13 19:04

nawara


1 Answers

Your UML design's not good enough. Skip the ugly & difficult-to-read 'styling', show us 'Vertex' as well as 'Edge', and an association diagram; not your (potentially over-complicated) idea of inheritance.

Your APIs, design & fundamental question are not really clear. 'Hyperedge' classes could represent a single instance of an Edge, and associate the two ends of that; or they could (if better named) represent an Edge Type, and search the graph globally from a specified Endpoint parameter.

These are complelely different designs, your question is meaningless until you figure the above out.

Either way, Edge.search() doesn't have the right signature. Where VS and VE are start and end vertex-types, and TE is edge-types, it should either be:

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

or

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

The nearest-neighbour algorithm should be implemented using generic types, and then called as required (with exact type-signatures) by the concrete classes.

BTW, when you mention "nearest neighbor"; Neither is it clear if "nearest neighbour" means directly connected vertex, which is trivial, or to find the nearest distant (how is distance measured? you don't specify) vertex of a specified type.

Either way, the utility & correctness/ need to implement subtypes of 'Edge' seems unclear. Many graph algorithms find Vertices/Nodes to be interesting and subtype these, but I am less than aware of subtyping (or the utility of subtyping) the edges leading to these.

Last tip: ditch the complex naming, KISS. 'Vertex' and 'Edge' will help you get a clear, simple, comprehensible & correct design. Save the extra wordage for after you've got that.


In response to further info from Nawara:

Then it's an EdgeType you've modelled, and when asking 'nearest neighbor' you should take a Start Vertex & return either Edge(s) -- if you need the distance metrics -- or Vertices.

The reference to 'Graph' should be probably implicit from the Vertex parameter.

As far as your EdgeType inheritance heirarchy: subtypes & inheritance should be defined to follow behavioural characteristics, not the generic types (Vertex types) they reference. The principle for OO class heirarchy design is to model doing, not being.

In this regard you might have a KnnDistanceEdgeType & FlickrDistanceEdgeType classes, either as ancestors, or, if no other method behaviour needs to be different, as the actual implementing classes. The feature types/classes they're searching for can be set as properties -- with properties & genericized differently, to answer different Vertex types.

eg.

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);

If there is much other behaviour (we haven't defined any, and can't imagine much) in EdgeType, you could move the KNN- and Flickr-distance algorithms off to separate classes. Probably no need.

Remember: in OO, subclass for behaviour, not for existence. And give me a +1 vote!

like image 102
Thomas W Avatar answered Oct 11 '22 17:10

Thomas W