ArrayList in mehrern Klassen verfügbar machen

Hallo,

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.

Wie kann ich denn dieses Problem lösen?

Danke

GGK

Moin,

Und wieso wäre das ein Problem??
Das ist halt OOP …

Aber zeig’ doch mal mehr Code, damit man erahnen kann, was Du eigentlich vorhast!

Gruß Klaus

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:

this.resultQry=DatenbankConnection.resultQry;

GGK

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.

GGK

[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…

bye
TT

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 :wink:

Ok, dann hol mal Popcorn, und wir schauen ein Video…

//youtu.be/-FRm3VPhseI

bye
TT

Ich danke Euch allen für die rasche Unterstützung.
Ich habe das nun endlich mit den Konstruktoren geschnallt…hoffentlich auch dauerhaft :wink:

GGK

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.

der Vollständigkeit halber verlangt ThreadLocal Erwähnung :wink:

[ot]

[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]