Ja, Sie können das Flyweight-Muster mit Hibernate implementieren.
Das Flyweight-Muster ist eine Möglichkeit, die Speichernutzung zu minimieren pro Instanz. Die Strategie besteht darin, so viele Zustände wie möglich zwischen Fliegengewicht-Instanzen zu teilen. In Ihrem Fall ist der gemeinsam nutzbare Status alles außer dem Hibernate-Objektbezeichner und einem zusätzlichen Status zur Beibehaltung der Objektidentität.
Jede Fliehgewicht-Instanz benötigt eine eigene object identity. Der zusätzliche Status ist die Art und Weise, Identität zu implementieren, um zwischen Objekten mit gemeinsamem Status zu unterscheiden.
public boolean equals(Object obj){
Fly other; [..]//check type
//null checks ommitted
return other.myState.equals(myState) && other.commonState.equals(commonState);
}
Wenn die Objektidentität zwischen Instanzen gemeinsam genutzt wird winter würden alle physischen Instanzen (Referenzen) als die gleiche Instanz interpretieren. Hibernate verwendet die equals-Methode, um die Objektidentität zu überprüfen, und Ihre gleichwertige Implementierung müsste (! a.equals(a) == true)
zurückgeben, was illegal ist. Equal muss reflexiv sein. Wenn Sie diesen Vertrag brechen, werden alle Bibliotheken, die vom Vertrag abhängig sind, unterbrochen (Sammlungen, Ruhezustand usw.).
Sie können die Methode equal nicht implementieren, indem Sie den Objektnamen des Hibernate-Objekts verwenden, um zwischen Objekten zu unterscheiden. Dies würde die Objektidentität von dem Persistenzzustand abhängig machen (persistent oder transient).
Eine Möglichkeit, den gemeinsamen Status im Ruhezustand zu modellieren, ist eine Eins-zu-Viele-Verknüpfung zwischen Objekten mit gemeinsam genutztem Status und Objekten mit Fliegengewicht. (Vielleicht hat jemand eine Idee, wie man die Daten abbildet, ohne zwei Tabellen zu verbinden?)
String: Nur internalized strings wird geteilt. Dies ist die meiste Zeit nicht die beste Lösung. Es eignet sich für Symbole (Klassenname, Methodenname usw.). Die internalisierten Strings werden niemals von Müll gesammelt und Sie müssen eine String-Instanz haben, die sowieso Müll gesammelt werden soll new String("..").intern()
. Es werden keine Zuordnungen gespeichert. Es gibt nur den geringfügigen Vorteil, dass die Basiszeichenfolge eine GC-Generation nicht überlebt oder auf dem Stapel zugeordnet werden könnte (mit der Escape-Analyse in Hotspot aktiviert und anwendbar).
Der Benutzertyp ist eine gute Idee, um den gemeinsamen Status der Fliegengewicht-Instanzen abzubilden. (Hibernate und JDBC werden immer noch viele Instanzen initiieren. Dazu gibt es keinen Weg. Zumindest werden sie ziemlich schnell zur Garbage Collection.) Kann ein CompositeUserType den gesamten Common State in einem Objekt repräsentieren? –
Ja, ein zusammengesetzter Benutzertyp könnte das wahrscheinlich tun, aber warum hat die Entität überhaupt eine Entität? Sei einfach von Anfang an ein Wertobjekt (Komponente). –