2013-04-17 1 views
9

Mein Projekt ist ein Hyper in JavaWie vermeidet man die Duplizierung von Code in diesem Fall?

Mein Hyper verschiedenen Arten von Hyperkante enthalten je nach Typ Vertex, die ich

Vertex Typ über die Implementierung haben: Bild, Tags ...

Hyperkante = Homogeneous (beziehen Scheitel gleichen Typs)/Heterogeneous (beziehen Scheitel von einem anderen Typ)

Homogeneous Hyperkante = Bild-Bildhyperkante/Tag-Tag-Hyperkante

Thi s ist ein schnell UML-Diagramm

enter image description here

enter image description here zeichnen das ist mein 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; 
    } 
} 

das Problem ist in der ImageImageHyperEdge Klasse sollte ich wissen, was ist die Art der darauf basierenden Funktion Ich suche die nächsten Nachbarn von ImageVertex Ich kann nicht in die abstrakte Methode der Super-Schnittstelle übergeben, da TagTagHyperEdge Klasse es nicht

brauchen und wenn ich ImageImageHyperEdge Klasse von {featureOneHyperEdge Klasse, ... featureFiveHyperEdge Klasse} ersetzen (in denen ich weiß, die Feature-Typ) wird es eine Duplizierung von Code sein, wie es die gleichen nächsten Nachbarn Suchalgorithmus ist


feature = Low-Pegel Merkmal eines Bildes (Farb Histogramm zum Beispiel)
I 5-Typ mit niedrigem Pegel haben Feature
Ich werde jeden verwenden, um die nächste ne zu suchen ighbors meines aktuellen Bild
All Funktion werden in einer einfachen Textdatei
der gleiche Algorithmus bestückte verwendet wird, um die nächsten Nachbarn
nur die Datei jedes Mal

+0

Ich bin mir nicht sicher, ob ich richtig verstanden habe, was Sie brauchen, also könnte dies in beide Richtungen gehen. Können Sie eine Basisklasse BaseFeatureHyperEdge haben, die den Suchalgorithmus implementieren würde? Und legen Sie eine Art von Template-Methode offen, die von FeatureOneHyperEdge, FeatureTwoHyperEdge usw. überschrieben wird. Diese Vorlagenmethode sollte nur den Typ der Funktion bereitstellen, auf der die Suche basiert. Ich hoffe es hilft? –

+0

@DenisRosca die erste Idee, die ich habe, ist das Strategie-Muster zu verwenden Ich denke, es ist ähnlich wie Vorlage Muster können Sie mehr Sie Idee bitte erklären? – nawara

+0

Ich denke, ich werde eine Antwort hinzufügen –

Antwort

0

Basierend auf, was Sie geschrieben über „Funktion geändert wird, suchen "Ich würde sagen, dass dies als ein Feld in Ihrer ImageImageHyperEdge-Klasse geeignet wäre. Sie können eine FeatureType-Klasse mit den verschiedenen Elementen erstellen, die sie definieren.

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

    private FeatureType featureType; 

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

die Feature-Unterklasse wird die konkrete Implementierung erben, aber wie wird es den Feature-Typ wissen? – nawara

+0

Würde die Klasse selbst nicht den Feature-Typ angeben? Wie würde FeatureOneHyperEdge nicht anzeigen, dass der Feature-Typ "FeatureOne" ist? –

+0

ja, aber wie die konkrete Umsetzung in der Superklasse wird es wissen? – nawara

0

Versuchen Sie etwas wie das?

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

Vielleicht können Sie die Template Method Pattern versuchen?

+0

verstehe. Ich habe keine Ahnung – nawara

1

Ihr UML-Design ist nicht gut genug. Überspringe das hässliche & schwer zu lesende 'Styling', zeig 'Vertex' sowie 'Edge' und ein Assoziationsdiagramm; nicht Ihre (möglicherweise zu komplizierte) Idee der Vererbung.

Ihre APIs, Design & grundlegende Frage sind nicht wirklich klar."Hypergedge" -Klassen könnten eine einzelne Instanz eines Edge darstellen und die beiden Enden davon verbinden; oder sie könnten (wenn besser benannt) einen Kantentyp darstellen und das Diagramm global von einem angegebenen Endpunktparameter aus durchsuchen.

Dies sind völlig verschiedene Designs, Ihre Frage ist bedeutungslos, bis Sie die oben genannten herausfinden.

Wie auch immer, Edge.search() hat nicht die richtige Signatur. Wo VS und VE sind Start- und Endknoten-Typen und TE ist kanten Typen, sollte es entweder:

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

oder

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

Der Nächster-Nachbar-Algorithmus sollte mit generischen Typen implementiert werden und dann wie erforderlich (mit genauen Typ-Signaturen) von den konkreten Klassen aufgerufen.

BTW, wenn Sie "nächster Nachbar" erwähnen; Es ist auch nicht klar, ob "nächster Nachbar" direkt verbundenen Vertex bedeutet, was trivial ist, oder um den nächstgelegenen (wie wird Abstand gemessen? Sie geben nicht an) Vertex eines bestimmten Typs zu finden.

In jedem Fall scheint das Dienstprogramm & Korrektheit/Notwendigkeit, Subtypen von 'Edge' zu implementieren, unklar. Viele Graphalgorithmen finden Vertices/Nodes interessant und unterteilen diese, aber mir ist nicht bewusst, dass die Kanten, die zu diesen führen, untergeordnet sind (oder die Nützlichkeit der Subtypisierung).

Letzter Tipp: Graben Sie die komplexe Benennung, KISS. 'Vertex' und 'Edge' werden Ihnen helfen, ein klares, einfaches, verständliches & korrektes Design zu erhalten. Speichern Sie das zusätzliche Wort für nach Sie haben das.


Als Antwort Infos von Nawara zu fördern:

Dann ist es ein EdgeType Sie modelliert haben, und als ‚nächster Nachbar‘ fragen Sie sollten einen Anfang Vertex & Rückkehr entweder Edge (n) nehmen - wenn Sie die Entfernungsmetriken - oder Vertices benötigen.

Der Verweis auf 'Graph' sollte wahrscheinlich vom Vertex-Parameter impliziert werden.

Soweit Ihre EdgeType Vererbungshierarchie: Subtypen & Vererbung sollte Verhaltensmerkmale, nicht die generischen Typen (Vertex-Typen), die sie verweisen, zu folgen. Das Prinzip für die OO-Klassenhierarchiestudie ist das Modell doing, nicht ist.

In diesem Zusammenhang haben Sie möglicherweise eine KnnDistanceEdgeType & FlickrDistanceEdgeType-Klassen entweder als Vorfahren, oder, wenn kein anderes Methodenverhalten unterschiedlich sein muss, als die tatsächlichen implementierenden Klassen. Die Feature-Typen/Klassen, nach denen sie suchen, können als Eigenschaften festgelegt werden - mit den Eigenschaften &, die auf andere Vertex-Typen unterschiedlich antworten.

z.

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

Wenn es viel anderes Verhalten ist (wir leider noch nicht definiert und kann sich nicht vorstellen, viel) in EdgeType, könnten Sie die KNN- und Flickr-Abstand Algorithmen aus den einzelnen Klassen bewegen. Wahrscheinlich keine Notwendigkeit.

Erinnern Sie sich: in OO, Unterklasse für Verhalten, nicht für Existenz. Und gib mir eine +1 Stimme!

+0

Ich habe einen komplexen HyperGraph G = (V, E), V ist der Scheitelpunkt, der verschiedene Arten von Scheitelpunkten enthalten kann (Bild, Tag) , locaetion ...) und E ist der HyperEdge-Satz, der auch einen anderen Kantentyp enthält (Kante zwischen Bildern, zwischen Tags, zwischen Bild und Tag) Die Art des Auffindens von Inzisionscheitel jeder HyperEdge unterscheidet sich je nach HyperEdge-Typ für Beispiel im Fall von hyperEdge, deren Start und Endpunkt Bild Vertex sind Ich benutze den KNN Algorithmus (mit euklidischen Abstand) im Falle von HypeEdge, deren Anfang und Ende sind Tags Ich benutze die Flickr Distanz – nawara

+0

das ist, warum ich denke, ich sollte verwenden eine abstrakte Klasse "hyperged" und mehrere Unterklassen erben von ihr und jeder repräsentiert einen anderen HyperEdge-Typ e – nawara

+0

In diesem Fall handelt es sich um einen EdgeKind oder EdgeType - und Sie fragen ihn, ob Sie ein StartVertex angeben und eine Kante oder einen Scheitelpunkt als Ergebnis beantworten möchten. Edge, wenn Sie die Entfernung benötigen, Vertex, falls nicht. –

Verwandte Themen