ich komme im Moment gar nicht mit folgendem Problem klar:
Ich habe eine Klasse Datenbank die ich aus der Klasse Model aufrufe und den Rückgabewert der Datenbank-Abfrage in eine ArrayList (=resultQry) speichere.
Klasse Model:
private DatenbankConnection db = new DatenbankConnection();
ArrayList<String> resultQry = db.doQuery(sqlStatement);
public ArrayList<String> getResults() {
return resultQry;
}
Wenn ich nun aus einer anderen Klasse (Storage-Klasse) auf diese ArrayList zugreifen möchte, dann gelingt mit das nicht da ich ja eine neue Instanz der Klasse Model aufmachen muss um auf die getter Methode in der Klasse Model zuzugreifen.
ich setze die ArrayList in der Klasse DatenbankConnection.
In der Klasse Model greife ich auf die Datenbank zu und hole mir auch die ArrayListe in diese Klasse.
Nun muss ich auch noch in der Klasse Storage auf diese ArrayListe zugreifen.
wenn ich private DatenbankConnection db = new DatenbankConnection();
aus zwei verschiedenen Klassen ausführe, dann habe ich doch zwei verscheidene ArrayListen und eine bleibt leer.
Lösen kann ich das nur mir der hässlichen statischen Variante:
Erst einmal Denglisch vermeiden: DatenbankVerbindung **oder **DatabaseConnection, kein Gemisch.
Dann ist eine einfache Möglichkeit um Ressourcen zu verteilen, diese im Konstruktor mitzugeben:
public class Application {
public static void main(String... args) {
DatabaseConnection con = new DatabaseConnection();
A a = new A(con);
B b = new B(con);
...
}
}
public class A {
private final DatabaseConnection con;
public A(DatabaseConnection con) {
this.con = con;
}
}
public class B {
private final DatabaseConnection con;
public B(DatabaseConnection con) {
this.con = con;
}
public C makeC() {
return new C(con); //wieder weitergegeben
}
}
public class C {
private final DatabaseConnection con;
public C(DatabaseConnection con) {
this.con = con;
}
}
^ Das, nur müßte (wenn ich das richtig sehe) nicht die Connection, sondern die ArrayList im Konstruktor übergeben werden. (Das könnte man auch auf vielen Ebenen hinterfragen, aber … vom Grundgedanken her würde es so laufen)
Könnt ihr mir sagen, nach welchen Schlagworten ich mich in der Literatur dazu schlau machen kann?
Ich glaube, auch Vererbung könnte da ein Thema sein, das ich mir dazu anschauen sollte.
[quote=GGK]Könnt ihr mir sagen, nach welchen Schlagworten ich mich in der Literatur dazu schlau machen kann?[/quote]Dependency Injection ist das Schlagwort.
[quote=GGK;129153]Ich glaube, auch Vererbung könnte da ein Thema sein, das ich mir dazu anschauen sollte.[/quote]Das nun gerade nicht…
Wieder einer der Fälle, wo ein Ratschlag „zu gut gemeint“ sein kann. Also, bei Fragen wie „Was ist ein Setter?“ oder „Was ist ein Konstruktor?“ kann man sagen: „Joa, das ist alles nicht mehr so wichtig wenn man Spring oder OSGi verwendet“. Aber konkret in diesem Fall: Übergib’ die ArrayList im Konstruktor. Nächster Schritt: Verstehen, warum es nicht ArrayList sondern List heißen sollte
Prinzipiell kann man solche Werte auch später (mit Setter-Methoden) setzen, allerdings besteht dann immer die Gefahr, dass man eine Nullpointer-Exception bekommt, wenn man versucht, den Wert vorher zu lesen.
Wie schon erwähnt gibt es andere Lösungsmöglichkeiten, die aber entweder schlecht sind, informierte Abwägung erfordern und/oder für dich zu kompliziert sind:
Singletons, Klassenvariablen: Das Java-Äquivalent zu globalen Variablen und meistens eine schlechte Idee
statische Methoden, Factory-Pattern: kann manchmal sinnvoll sein, man braucht aber etwas Erfahrung, um das einschätzen zu können
Abstract Factory Pattern: kompliziert, lohnt sich nur in speziellen Situationen
Dependency Injection: bequem, aber Abhängigkeit von Framework (Guide, Spring…) und Overkill für Anfänger
dynamisches Laden von Komponenten (SPI, OSGi): nur in größeren, erweiterbaren System sinnvoll
Ich würde dazu raten, erst einmal bei der Konstruktor-Variante zu bleiben.
[QUOTE=Timothy_Truckle;129158]Ok, dann hol mal Popcorn, und wir schauen ein Video…
[/QUOTE]
Ich weiß, dass man es “besser” machen kann. Variablen, Ifs, Schleifen, Klassen, Getter/Setter, … man muss irgendwo anfangen, und ich will nicht sagen, dass man sich notwendigerweise alle 19 Kapitel aus “Java ist auch eine Insel” durchgelesen haben muss, bis man “Mehr als eine Insel” liest und dort im Kapitel 17 das erste mal über “Dependency Injection” stolpert - die Probleme, die mit globalen UND (!) schon mit (“nur”) geteilten Zuständen (wie etwa einer ArrayList, die man rumreicht) verbunden sind, kann man durchaus auch früher vermitteln. Aber bei der Frage “Wie kann man eine ArrayList irgendwo hin übergeben?” sollte die Antwort IMHO nicht lauten “Schau’ dir erstmal die AbstractSingletonProxyFactoryBean an, du n00b” (überzogen, ja, aber zur Verdeutlichung). Man kann zwar eine Schlucht nicht mit zwei Sprüngen überwinden, aber manchmal muss man doch einzelne Schritte machen.
[/ot]