# Vector in vielen Klassen



## PollerJava (26. Sep 2007)

Hallo,

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?

lg


----------



## Murray (26. Sep 2007)

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:

```
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?


----------



## Marco13 (26. Sep 2007)

PollerJava hat gesagt.:
			
		

> Hallo,
> ...
> brache diesen Vector dann in sehr vielen Klassen,



... 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?


----------



## PollerJava (27. Sep 2007)

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,

lg


----------



## Marco13 (27. Sep 2007)

PollerJava hat gesagt.:
			
		

> 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,


Schlecht.



			
				PollerJava hat gesagt.:
			
		

> 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,


Auch schlecht.

Niemand kennt deine Klassenstruktur und das genaue Problem, aber sinngemäß könnte/sollte man es vielleicht so machen

```
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.


----------



## PollerJava (27. Sep 2007)

naja, ich lese aus einer XML- Datei in den Vector ein und brauche die Daten dann in einigen Klassen,
das ist alles,

Das dachte ich mir eben, dass ich in jeder Klasse, in der ich auf den Vektor zugreifen will, eine Instanz benötige,

Wie kann ich das besser machen??

lg


----------



## Murray (27. Sep 2007)

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.


----------



## PollerJava (27. Sep 2007)

JA aber dann bin ich wieder bei static und das ist ja nicht das Beste, jetzt hab ich es eh so wie Du


----------



## Murray (27. Sep 2007)

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.


----------



## Gast (27. Sep 2007)

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


----------



## Wildcard (27. Sep 2007)

Singelton ist hier definitiv falsch, weil es nicht darum geht zu verhindern das es mehr als eine Instanz gibt.


----------



## Marco13 (27. Sep 2007)

... 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 (27. Sep 2007)

Was sollte da der Vorteil gegenüber static sein?


----------



## Marco13 (27. Sep 2007)

@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ß.


----------



## Wildcard (27. Sep 2007)

@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.


----------



## PollerJava (28. Sep 2007)

Wildcard hat gesagt.:
			
		

> Singelton ist hier definitiv falsch, weil es nicht darum geht zu verhindern das es mehr als eine Instanz gibt.



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:


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

Zugriff von den verschiedenen Klassen 

```
Control.getStatesSize();
Control.getStatesElementAt(0). ...
```

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,

lg


----------



## Murray (28. Sep 2007)

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)


----------



## Marco13 (28. Sep 2007)

PollerJava hat gesagt.:
			
		

> Wenn ich das Ganze nicht static mache, dann benötige ich sehr vielen Instanzen auf die Klasse, welchen den Vector beinhaltet



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.


----------



## Wildcard (28. Sep 2007)

@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.


----------



## PollerJava (30. Sep 2007)

Wie funktioniert das, einen Vectro über eine List oder eine Collecten anzusprechen?

lg und vielen Dank


----------



## Marco13 (30. Sep 2007)

Nicht

```
private Vector data = new Vector();
```
sondern

```
private List data = new Vector();
```
nehmen - und entspechend bei Methoden nicht

```
void setData(Vector data) {...}
```
sondern

```
void setData(List data) {...}
```
Ganz pragmatisch: ÜBERALL nicht 'Vector' sondern 'List' schreiben. Die EINZIGE Ausnahme ist die Erstellung (mit "new Vector()")


----------



## PollerJava (1. Okt 2007)

Dankeschön!!!

lg


----------

