Designfrage

Status
Nicht offen für weitere Antworten.

SabineMA

Mitglied
Hallo!
Ich habe folgendes Design-Problem:

Ziel ist eine Anwendung mit RMI, Datenbankanbindung und so.

Aus einer Datenbank hole ich Tabellen. Da ich das ResultSet nicht über RMI transportieren kann, habe ich dafür folgende Lösung:

Ich habe später auf Server und Client in einem package Klassen wie z.B.

BeanKunde (stellt Datensätze aus der Datenbank-Tabelle tblKunde als Objekte dar und hat dazu nur Getter und Setter)
BeanAuftrag (stellt Datensätze aus der Datenbank-Tabelle tblAuftrag als Objekte dar und hat dazu nur Getter und Setter)
...

Auf dem Server werden Datensätze aus der Datenbank geholt und das ResultSet in ein Array z.B. aus BeanKunde-Objekten "umgewandelt". Dieses wird dann an den Client weitergereicht, der das ganze in einer Tabelle darstellen soll.

Nun bin ich dabei, mir ein eigenes TableDataModel zu schreiben, dessen Konstruktor aus einem Bean-Array ein Object-Array für die JTable machen soll.
Ich möchte aber nicht für jede einzelne Klasse BeanKunde, BeanAuftrag, etc. einen eigenen Konstruktor machen, sondern statt dessen eine Super-Klasse "Bean" als Parameter für den Konstruktor übergeben, der das alles irgendwie (!) mit einem Schlag erledigt.

Derzeit überlege ich, wie ich die Spaltenüberschriften der JTable erstellen kann. Meine Idee war, in jeder BeanXXX-Klasse ein statisches String-Array zu haben, in dem die Spaltenüberschriften enthalten sind.

Jetzt fängt die Problematik an: Ich habe den ganzen Tag rumgewurschtelt und hin und her überlegt, aber mir fällt keine Lösung für die Sache ein. Meine bisherigen Ansätze:

1. Super-Klasse "Bean" (abstract), mit einer statischen Methode "getHeader(int column)", welche aus den davon abgeleiteten Klassen BeanKunde etc. die Spaltenüberschriften zurückgibt. Ich möchte diese Methode - getHeader - die für jede Bean gleich aussieht, nicht in jeder Klasse stehen haben. (Funktioniert nicht, anscheinend hat mir das static Probleme gemacht?).

2. Bei der JTable mit InstanceOf arbeiten (funktioniert zwar, aber lästig wegen Fallunterscheidung für jede einzelne Bean).

Ergo: Ich möchte das das ganze auch noch läuft, wenn ich mal eine neue Bean-Klasse erstelle, mag dann nicht überall im Code was ändern müssen.

Auf jeden Fall steh ich ziemlich auf dem Schlauch und komm einfach nicht weiter.

Vielleicht hat von Euch jemand ne Idee? Wäre super...

Liebe Grüße, Sabine
 

Schreihalz

Mitglied
ich hoffe ich habe alles richtig verstanden und will jetzt keine richtig fertige Lösung vorschlagen. Allerdings fiel mir beim Lesen etwas ein:

warum machst du es nicht mit Hashtables? Jedes Bean-Objekt hätte sone Hashtable in sich, in der Keys die Namen der Spalten sind und die entsprechenden Werte die Values.
 

SabineMA

Mitglied
Hm, ich hab leider keine Ahnung was du genau meinst, aber beim Googeln habe ich gelesen, dass ne Hashtable eher für große Datenmengen gedacht ist.
Ich poste mal ein bißchen Code zum besseren Verständnis:

Meine Klasse BeanCountry
Code:
package beans;

public class BeanCountry extends Bean {

	public final static String[][] HEADERS = { { "Länderkennzeichen", "Land" },
			{ "Country indicator", "Country" } };
	
	private String countryIndicator;
	private String country;

	public BeanCountry(String countryIndicator, String country) {
		this.countryIndicator = countryIndicator;
		this.country = country;
	}
	
	/*
	 * Getter und Setter hab ich hier jetzt weggelassen
	 */
}


Meine Klasse Bean
Code:
package beans;

public abstract class Bean {

	public final static int LANG_GERMAN = 0;
	public final static int LANG_ENGLISH = 1;


	public String getHeader(int language, int column) {
				
		try {
			if (this instanceof BeanCountry) 
				return BeanCountry.HEADERS[language][column];
		        //hier werden spätere noch alle anderen BeanXXX-Klassen durchgetestet
		} catch (IndexOutOfBoundsException e) {
			System.out.println("ERR: Index außerhalb des gültigen Bereichs.");
		}
		return "" + column;
	}
}

So, und jetzt hab ich irgendwo noch den Konstruktor aus obiger Erklärung. Diesen kann ich entweder für jede Klasse BeanXXX mit einem anderen Parameter schreiben, oder ich mache es mit der Super-Klasse Bean, wie hier:

Code:
public class Irgendeine{

	public Irgendeine(Bean[] b) {
				
		System.out.println(b[0].getHeader(Bean.LANG_ENGLISH , 0));
		System.out.println(b[0].getHeader(Bean.LANG_ENGLISH , 1));		

	}
}

Soweit bin ich mittlerweile gekommen. Das klappt auch alles ganz wunderbar, das einzige Problem:
Was mache ich, wenn ich in meinem Bean keine Daten habe? Sprich, das Array ist zwar da aber null. Irgendwie muss das doch noch anders gehen...
 

Mag1c

Top Contributor
Hallo Sabine,

hier die erste Korrektur:

Code:
package beans;

public abstract class Bean {

   public final static int LANG_GERMAN = 0;
   public final static int LANG_ENGLISH = 1;

   public abstract int getColumnCount ();

   public abstract String getHeader (int language, int column);

}

package beans;

public class BeanCountry extends Bean {

	public final static String[][] HEADERS = { { "Länderkennzeichen", "Land" },
        { "Country indicator", "Country" } };

	public int getColumnCount () {
		return 2;
	}

	public String getHeader (int language, int column) {
		return HEADERS[language][column];
	}
}

Man könnte in der Klasse Bean auch eine setHeader-Methode implementieren und die Funktionalität von getHeader auch dorthin verlagern. Im Konstruktor der Klasse BeanCountry müsste dann mit setHeader die Header definiert werden. Die Verwendung von Sub-Klassen solltest du in der Ober-Klasse dringend vermeiden.

In der geänderten Fassung siehst du, daß in der Klasse Bean alles abstrakt ist. Sollte das so bleiben, d.h. es läßt sich kaum Code gemeinsam nutzen, sollest du stattdessen ein Interface Bean benutzen welches durch die spezifischen Bean-Klassen implementiert wird.

Allgemein ist aber zu hinterfragen, ob die Bean-Klassen (Auftrag und Kunde? Country?) überhaupt irgendwie etwas miteinander zu tun haben, damit sie eine gemeinsame Basisklasse haben. Wenn es nur darum geht, alles in ein universelles TableModel zu quetschen, kannst du auch spezielle TableModels für jede Bean-Klasse implementieren.

viele Grüße
Mag1c
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben