Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
ich fülle eine Vector in einer Klasse an (von einer externen XML- Datei) und brache diesen Vector dann in sehr vielen Klassen,
Momentan ist bei mir der Vector static und ich greife über Klassenname.Vectorname in allen Klassen darauf zu,
Ist das von Design her OK oder wie könnte ich das am Besten machen?
Das geht solange gut, wie a) der Inhalt des Vectors nur von der XML-Date anhängt und es b) auch nur eine Version der XML-Datei gibt. Dass es den Vector für eine XML-Datei nur einmal gibt, ist dann in Ordnung (und auch wünschenswert, denn das Einlesen kostet ja Zeit, und der Vector braucht auch Speicher).
Ich würde das in etwa so machen:
Code:
private static final HashMap<String,Vector> vectors = new HashMap<String,Vector>();
public static Vector getVector( File f) {
String path = f.getAbsolutePath();
Vector v = vectors.get( path);
if ( v == null) {
v = readVectorFromFile( f);
vectors.put( path, v);
}
return v;
}
private static Vector readVectorFromFile( File f) {
Vector v = new Vector();
/* ... */
return v;
}
Dieser Code berücksichtigt allerdings nicht, dass sich die XML-Datei evtl. während der Laufzeit ändern kann. Außerdem kann man evtl. ein Problem bekommen, wenn es sehr viele verschiedene XML-Dateien gibt; in diesem Fall wächst vectors immer mehr an.
BTW: gibt es einen Grund, warum du Vector verwenden willst und nicht List?
... klingt, als würde DORT das eigentliche Problem liegen. Wozu brauchst den Vector in vielen Klassen? Kannst du den Vector nicht in EINER Klasse liegen lassen, und andere Klassen indirekt (und damit, ganz nebenbei, implementierungsunabhängig!) darauf zugreifen lassen?
Ja das habe ich jetzt gemacht, allerdings ist der Vektor in der einen Klasse static und über eine Klassenmethode greife ich von der verschiedenen Klassen auf diesen Vekor zu,
Ist das vom Design her OK oder ist es eher besser, in jeder Klasse, in der ich Zugriff auf den Vektor haben will, eine Instanz der Klasse, die den Vektor besitzt, anzulegen,
Ich hab mir das momentan so gedacht, dass der Vektor ja für alle Objekte da ist und deshalb die den Vektor als Klassenvariable gesetzt,
Ja das habe ich jetzt gemacht, allerdings ist der Vektor in der einen Klasse static und über eine Klassenmethode greife ich von der verschiedenen Klassen auf diesen Vekor zu,
Ist das vom Design her OK oder ist es eher besser, in jeder Klasse, in der ich Zugriff auf den Vektor haben will, eine Instanz der Klasse, die den Vektor besitzt, anzulegen,
Niemand kennt deine Klassenstruktur und das genaue Problem, aber sinngemäß könnte/sollte man es vielleicht so machen
Code:
class ClassWithElements
{
private Vector vector = ...
public int getNumElements() { return vector.size(); }
public Element getElement(int i) { return vector.get(i); }
}
class OtherClass
{
private ClassWithElements classWithElements = REFERENZ auf die eine Instanz von ClassWithElements, die es gibt
void foo()
{
Element element = classWithElements.getElement(0); // "indirekter" Zugriff auf den Vector
}
}
class AnotherClass
{
private ClassWithElements classWithElements = REFERENZ auf die eine Instanz von ClassWithElements, die es gibt
}
class YetAnotherClass
{
private ClassWithElements classWithElements = REFERENZ auf die eine Instanz von ClassWithElements, die es gibt
}
Dass alle Klassen die eine Instanz kennen müssen, ist auch nicht so toll, aber wie man das vermeiden kann, ist eine Architekturfrage, die man nicht beantworten kann, wenn man nicht weiß, was du vorhast.
Mit der (Klassen-)Methode, die ich oben gepostet habe, kann man sich an jeder beliebigen Stelle eine Instanz des Vectors holen, ohne dass dabei wirklich mehr Instanzen erzeugt werden als notwendig; man braucht lediglich den Import auf die Klasse, in der die Methode deklariert ist.
static ist aber doch nicht per se irgendwie böse. Ungünstig wäre hier nur, den Vector selbst static zu machen, weil man dann in einer VM nur noch eine Instanz haben kann.
Beim Lesen dieses Thread muß ich irgendwie immer an Singelton denken.
Es gibt ein Pattern, das Singelton Pattern, das sorgt dafür, das es von einem Objekt nur eine Instanz gibt. Richtig implementiert, wird auch nur einmal instanziiert. Das Funktioniert eigentlich recht simpel. Schau einfach mal nach Singelton und entscheide dann ob es vielleicht das ist was du haben möchtest
... und falsch angewendet wird es zur Struktur-Hölle. Wer mal ein Programm warten mußte, das aus einer losen Sammlung von Singeltons besteht, weiß, was ich meine. Aber hier könnte es sogar angebracht sein. Wer weiß.
@Wildcard: Wenn dieses Singleton sozusagen einzig und allein den Inhalt einer einzigen Datei auf der Festplatte bescheiben soll, könnte es nicht mal soooo falsch sein, aber ... ich mag Singletons nicht, weil sie (wie gesagt) zu schlechtem Stil verführen. Meistens kann man eine saubere, flexible Lösung finden.
EDIT: Hatte deine Nachfrage nicht gesehen. Da Singeltons auch static sind, ist beides IMHO nur in den seltenSTEN Fällen angebracht.
@PollerJava: Vielleicht(!) wäre es auch sinnvoll, den Vector an die Methoden zu übergeben, die ihn brauchen. (Nochmal: ) Wer weiß.
@Marco13
ok, in einem sehr speziellen Szenario gebe ich dir recht.
Ich meide Singeltons wo immer möglich und auch hier ist sehr fraglich ob es eine brauchbare Alternative darstellt.
Das sehe ich aus so, Ich hab jetzt Singletons eingebaut, wos Sinn gemacht hat, z. B.: bei meiner CRCBerechnungs- Klasse, da will ich nur eine Instanz haben, ausserdem mag ich Singeltons auch nicht so, sie sind zwar praktisch, da man nicht lange nach einem Objekt einer Klasse suchen muss aber mit dem Erweitern is es dann halt so eine Sache,
Mein Stand ist momentan so:
Code:
private static Vector<ElementState> states; // Vector
public static ElementState getStatesElementAt(int index) // Zugriff auf ein Element des Vectors
{
return states.elementAt(index);
}
public static int getStatesSize() // Größe des Vectors, wurde mit trimSize() auf die wirkliche Größe angepasst
{
return states.size();
}
Meine Überlegung ist halt, dass es diesen Vector in meinem Programm nur einmal geben soll (da sehr groß) und dass diesen Vector einige Klassen benötigen.
Wenn ich das Ganze nicht static mache, dann benötige ich sehr vielen Instanzen auf die Klasse, welchen den Vector beinhaltet und das find ich auch nicht sehr gut,
Könnte ich es so lassen oder gibts vielleicht noch eine bessere Lösung in meinem Fall,
Ob dein Vector bzw. die XML-Datei, aus der er erzeugt wird, in einer VM definitiv immer der gleiche ist, kannst nur du entscheiden. Wenn das gegeben ist, ist der Ansatz doch OK. Wenn in einer VM auch mehrere verschiedene Vektoren gleichzeitig gebraucht werden -> s.o. (Dateinamen bei der statischen get-Method übergeben, unter der Haube eine statische Liste führen, nur dann eine neue Instanz erzeugen, wenn noch keine passende Instanz in der Liste vorhanden ist)
Eben nicht. An jeder Stelle, wo genau dieser Vector verwendet wird, kannst du auch nur genau den einen Vector verwenden. Es kann ja mehrere Referenzen darauf geben. Und wie du die Referenzen an die Stellen bringst, wo sie benötigt werden, hatte ich dir schon gesagt: Entweder, du speicherst die Referenzen in den jeweiligen Klassen, oder übergibst die Referenzen an die jeweiligen Methoden, oder... du machst irgendwas statisches (so wie jetzt, oder mit einem Singleton) was beides nicht unbedingt schön ist.
@PollerJava
Wenn man schon den Vector benutzt, dann sollte man ihn grunhdsätzlich nur über List oder Collection ansprechen.
Denn sonst passiert genau das was du hier demonstrierst. Man ist versucht Methoden des Vectors wie elementAt zu verwenden, die keinen Vorteil bringen, aber zu allen anderen Collections inkompatibel sind.