Frage

Ich habe auf der Suche für einen generischen Weg, um deal mit die bidirektionale Assoziationen und ein Weg, um Griff die inverse updates im Handbuch geschrieben in Java-code.

Für diejenigen, die nicht wissen, wovon ich spreche, ist hier ein Beispiel.Unten sind meine aktuellen Ergebnisse der (unbefriedigende) Lösung.

public class A {
    public B getB();
    public void setB(B b);
}

public class B {
    public List<A> getAs();
}

Nun, wenn Sie beim aktualisieren irgendeinem Zweck des Vereins, um die Konsistenz zu wahren, das andere Ende muss auch aktualisiert werden.Entweder manuell jeder Zeit

a.setB(b);
b.getA().add(a);

oder indem man die passenden code in der setter - / getter und verwenden Sie eine benutzerdefinierte Liste Umsetzung.

Ich habe gefunden, eine veraltete, nicht betreute Projekt, dessen Abhängigkeiten nicht mehr verfügbar (https://e-nspire-gemini.dev.java.net/).Es beschäftigt sich mit dem problem mithilfe von Anmerkungen, die sind verwendet zu injizieren, den erforderlichen code automatisch.

Kennt jemand ein anderes framework, das sich mit diesem in einer generischen, unaufdringliche Art und Weise ala gemini?

ciao, Elmar

War es hilfreich?

Lösung

Google Sammlungen (aus dem Google-internen Code) - http://code.google. com / p / google-Sammlungen / ist kompatibel Java Generics (nicht nur kompatibel, verwendet sehr gut Generika)

Klasse bimap - http://google-collections.googlecode.com/svn/trunk/javadoc/index.html?http://google -collections.googlecode.com/svn/trunk/javadoc/com/google/common/collect/package-summary.html ermöglicht bidirektionale Assoziationen.

Einige dieser Klassen erwartet ihren Weg in JDK 7 zu machen.

Andere Tipps

Es sei denn Sie abstrahiert die setter, sind Sie gehen zu müssen, um irgendeine Art von event notification-Mechanismus.Wenn Ihre Objekte sind JavaBeans, dann sind Sie auf der Suche mit PropertyChangeSupport und brennen-Eigenschaft change-events.

Wenn Sie das tun (oder einen anderen Mechanismus für die Erkennung von änderungen), dann Glasiert Listen bietet eine ObservableElementList das könnte leicht verwendet werden auf Griff der Verein die Synchronisierung auf das Ende der Liste (D. H.zu Liste hinzufügen< A> Anrufe automatisch ein.setB(b)).Die andere Richtung ist einfach in der Handhabung mit änderung der Eigenschaft überwachung (oder gleichwertig).

Ich weiß, es ist nicht eine generische Lösung, aber es scheint so, als wäre es eine leichte foundation für einen.

Beachten Sie, dass so etwas wie dieses erfordern eine Besondere Liste ist die Umsetzung in der B-Klasse keine Möglichkeit, kurz AOP-Typ-Lösungen, die Sie behandeln konnte, in den Allgemeinen Fall (D. H.Verwendung von ArrayList oder etwas wie, dass).

Ich sollte auch darauf hinweisen, dass das, was Sie versuchen, zu erreichen, ist so etwas wie der Heilige Gral der Daten verbindlich.Es gibt einige gute Implementierungen für die Bindung an die Feldebene (Sachen wie Getter und setter) (siehe JGoodies Bindung und JSR 295 für Beispiele).Es ist auch eine wirklich gute Umsetzung für die Liste-Typ-Bindung (Glasiert Listen, nach oben).Wir verwenden sowohl Techniken, die im Konzert mit einander in fast allen unseren Anwendungen, aber haben es nie versucht zu gehen, ganz so Abstrakt sind, was Sie sind gefragt.

Wenn ich die Entwicklung dieses, ich würde sehen Sie etwas wie dieses:

AssociationBuilder.createAssociation(A a, Connector< A> ca, B b,  Connector< B> cb, Synchronizer< A,B> sync)

Connector ist eine Schnittstelle, die ermöglicht für eine einzige Schnittstelle für verschiedene änderungs-Typen.Synchronizer ist eine Schnittstelle, die aufgerufen wird, um machen Sie sicher, dass beide Objekte sind in der sync immer, wenn einer von Ihnen geändert wird.

sync(ChangeInfo info, A a, B b) // make sure that b reflects current state of a and vice-versa.  

ChangeInfo liefert Daten, anhand derer die sich verändert und was die änderungen waren.Wir sind.Wenn Sie versuchen, die wirklich halten, diese generische, dann sind Sie ziemlich viel haben zu punt die Umsetzung des Rahmen-Benutzer.

Mit der oben im Ort, es würde möglich sein, haben Sie eine Reihe von vordefinierten Konnektoren und Synchronisatoren, die erfüllen unterschiedlichen verbindliche Kriterien.

Interessant ist, die oben genannten Signatur der Methode ist ziemlich ähnlich wie der JSR 295 createAutoBinding () - Methode aufrufen.Objekte entsprechen den Anschluss.JSR 295 nicht der Synchronizer (stattdessen haben Sie eine verbindliche Strategie als ein ENUM - plus JSR 295 funktioniert nur mit Immobilien->Immobilien-Bindung, der Bindung ein Feld mit dem Wert eines Objekts auf das Objekt der Liste Mitgliedschaft in einem anderen Objekt, ist noch nicht einmal auf die Tabelle für Sie).

Um Sinn zu machen, werden diese calsses Peers sein. Ich schlage vor, ein Paket-private-Mechanismus (in Abwesenheit von Freund) auf Konsistenz zu halten.

public final class A {
    private B b;
    public B getB() {
        return b;
    }
    public void setB(final B b) {
        if (b == this.b) {
            // Important!!
            return;
        }
        // Be a member of both Bs (hence check in getAs).
        if (b != null) {
            b.addA(this);
        }
        // Atomic commit to change.
        this.b = b;
        // Remove from old B.
        if (this.b != null) {
            this.b.removeA(this);
        }
    }
}

public final class B {
    private final List<A> as;
    /* pp */ void addA(A a) {
        if (a == null) {
            throw new NullPointerException();
        }
        // LinkedHashSet may be better under more demanding usage patterns.
        if (!as.contains(a)) {
            as.add(a);
        }
    }
    /* pp */ void removeA(A a) {
        if (a == null) {
            throw new NullPointerException();
        }
        as.removeA(a);
    }
    public List<A> getAs() {
        // Copy only those that really are associated with us.
        List<A> copy = new ArrayList<A>(as.size());
        for (A a : as) {
            if (a.getB() == this) {
                copy.add(a);
            }
        }
        return Collection.unmodifiableList(copy);
    }
}

(Haftungsausschluss. Nicht getestet oder sogar kompilierte)

Meistens Ausnahme sicher (kann in Ausnahmefall auslaufen). Thread-Sicherheit, viel viele, Leistung, libraryisation usw. bleibt als Übung für den interessierten Leser.

Danke für alle Vorschläge. Aber keiner kam in der Nähe zu dem, was ich suchte, ich wahrscheinlich formulierte die Frage in einer falschen Weise.

Ich war auf der Suche nach einem Ersatz für zwilling so für eine Möglichkeit, dies auf eine unaufdringliche Art und Weise zu handhaben, ohne den Code mit endlosen Kontrollen und spezieller Liste Implementierungen verschmutzen. Dies erfordert natürlich für einen AOP basierten Ansatz, wie er von Kevin vorgeschlagen.

Wenn ich um ein wenig mehr sah, fand ich ein Paket von Gemini auf CNET, die alle Quellen und Abhängigkeiten mit Quellen enthalten. Die fehlenden Quellen für die Abhängigkeiten waren die einzige Sorge, die mich von der Nutzung gestoppt. Da nun alle Quellen zur Verfügung Fehler sind behoben werden. Falls sich jemand für diese aussieht: http://www.download.com/Gemini /3000-2413_4-10440077.html

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top