Designfrage

Status
Nicht offen für weitere Antworten.
O

Olel

Gast
Hallo,

ich habe gestern mit meinen Kollegen über ein kleines Problem diskutiert zu dem wir keine zufriedenstellende Lösung gefunden habe. Daher frage ich jetzt mal hier in die Runde um vielleicht einen guten Vorschlag zu erhalten.

Es geht darum ein gutes Design für folgenden Anwendungsteil zu entwickeln. Die Anwendung soll im Wesentlichen Objekte (sagen wir mal Kunden) z.B. in einer Tabelle verwalten und die Möglichkeit bieten diese Objekte persistent zu speichern. Dieses Speichern soll im ersten Ansatz in einer XML-Datei geschehen, in einer zweiten Version soll alternativ auch das Speichern in eine Datenbank implementiert werden.

Damit die Businesslogik nichts von der Implementierung der Persistierung wissen muss, soll das ganze natürlich hinter einem Interface versteckt werden. Dieses könnte z. B. wie folgt aussehen:

Code:
public interface ICustomerSaverLoader {

	public void save(Customer[] cus);
	
	public Customer[] load();
}

Die Entscheidung, welche Implementierung verwendet wird, können wir einer Factory (s. FactoryPattern) überlassen (ein Frameword zur DependencyInjection soll hier erstmal nicht verwendet werden).

Nun ist es aber so, dass die dateibasierte Implementierung (FileCustomerSaverLoader) einen Dateinamen benötigt, die datenbankbasierte (DatabaseCustomerSaverLoader) hingegen eine Datenbankverbindung. Weiterhin ist es so, dass der Benutzer den Dateinamen frei wählen kann. Dieser kann also nicht fest in der FileCustomerSaverLoader Implementierung codiert sein, sondern muss dieser von außen übergeben werden.

Und genau hier ist das Problem. Wie kann in der konkreten Implementierung den Dateinamen mitgeben, wenn ich doch innerhalb der Businesslogik nur das Interface kenne, welches dafür natürlich keine Methode zur Verfügung stellt?

Vielleicht gehe ich die Sache ja auch ganz falsch an. Für einen Hinweis wäre ich auf jeden Fall dankbar.

Grüße,
Ole
 
B

Beni

Gast
Einfache Lösung: eine weitere Methode "void askUserForImportantInformation()". In dieser Methode öffnet sich z.B. ein JFileChooser der den Datennamen abfragt.

Kompliziertere Lösung: weitere Interfaces welche die Abfragen machen. Damit kann man auch diese "Plugins" in view und model trennen.
 

ARadauer

Top Contributor
der Teufel liegt immer im Detail, is ist ja recht schön und gut, wenn man eine Schicht austauschen kann, wenn mans aber dann macht ist es doch nicht so einfach.


ich würde das interface so definieren
Code:
public void save(Customer[] cus, String[] args);
dann kannst du beliebieg zusätzliche argumente übergeben, die vielleicht von späteren implementierungen verwendet werden.

das grundlegende problem ist einfach, dass du nicht nur die persistenz schicht austauscht, sondern auch die logik veränderst -> der benutzer kann den speicherort bestimmen
 

Olel

Mitglied
Beni hat gesagt.:
Einfache Lösung: eine weitere Methode "void askUserForImportantInformation()". In dieser Methode öffnet sich z.B. ein JFileChooser der den Datennamen abfragt.

Also das geht gar nicht, finde ich. Das würde ja bedeuten, dass ich aus der Persistenzschicht auf die GUI zugreifen würde. Bäh! :)

Beni hat gesagt.:
Kompliziertere Lösung: weitere Interfaces welche die Abfragen machen. Damit kann man auch diese "Plugins" in view und model trennen.

Das versteh ich jetzt nicht wirklich. Kannst Du das noch mal ein bisschen ausführen bitte?
 

Olel

Mitglied
ARadauer hat gesagt.:
ich würde das interface so definieren
Code:
public void save(Customer[] cus, String[] args);
dann kannst du beliebieg zusätzliche argumente übergeben, die vielleicht von späteren implementierungen verwendet werden.

Hmm, finde ich auch ziemlich unschön. Ist dann so eine "offene" Schnittstelle, dann könnte ich die Methode überspitzt formuliert auch gleich "void doAnything(Object[])" definieren.

ARadauer hat gesagt.:
das grundlegende problem ist einfach, dass du nicht nur die persistenz schicht austauscht, sondern auch die logik veränderst -> der benutzer kann den speicherort bestimmen

Jein. Selbst wenn der Benutzer den Speicherort nun nicht selbst bestimmen soll, sondern die Businesslogik (auf Basis welcher Informationen auch immer - z.B. Datum und Uhrzeit) bestimmt wie der Dateiname lauten soll, würde das Problem das gleiche sein.
 

Natorion

Bekanntes Mitglied
Ich würd solche Spezialinformationen überhaupt nicht berücksichtigen sondern jede dieser Fast-DAOs soll einfach eine Methode können die eine Property-File ausliest in der die nötigen Informationen stehen.

Wenn du sowas nicht willst, im Konstruktur einfach einen String übergeben der den Initialisierungstring enthält, was immer der auch macht (zB Pfad oder eben Connectionstring).-
 

Olel

Mitglied
Natorion hat gesagt.:
Ich würd solche Spezialinformationen überhaupt nicht berücksichtigen sondern jede dieser Fast-DAOs soll einfach eine Methode können die eine Property-File ausliest in der die nötigen Informationen stehen.

Wenn du sowas nicht willst, im Konstruktur einfach einen String übergeben der den Initialisierungstring enthält, was immer der auch macht (zB Pfad oder eben Connectionstring).-

Ja, der Gedanke war uns auch schon gekommen, aber genau das ist nicht möglich, da der Dateiname ja immer ein anderer sein soll. Er kann also nicht aus einer Property-Datei ausgelesen werden und auch nicht im Konstruktor übergeben werden. Denn die Intanziierung der Klasse wird ja nicht von der Businesslogik gemacht (die soll ja eben nur das Interface kennen), sondern von einer Factory-Klasse. Und diese Factory weiß wiederum nichts von unterschiedlichen Dateinamen, die von der Businesslogik bestimmt werden müssen.

PS: In den von Dir sog. Fast-DAOs soll die Persistierung gar nicht erfolgen. Die sollen davon also gar nichts wissen, sondern es gibt eine eigene Klasse (s. Originalpost).
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben