Discussion:
Designen einer Datenbankschnittstelle
(zu alt für eine Antwort)
Thomas Chojecki
2008-12-16 14:46:19 UTC
Permalink
Hallo NG,

ich will eine Schnittstelle für das Schreiben und Lesen von Objekten in
die Datenbank realisieren.

Ein abstraktes Basismodel habe ich schon fertig, was für jede Datenbank
geerbt wird und dann halt die nötigen Methoden von dem zuständigen
Entwickler ausgeschrieben werden.

Das Ganze sieht im Moment ungefähr so aus:
public abstract class DBManager {

public abstract void verbinde(String host, int port, String db,...);
public abstract void trenne();
public abstract boolean istVerbunden();

public abstract void schreibeObjekt1(Objekt1 o1);
public abstract void schreibeObjekt2(Objekt1 o2);

public abstract Objekt1 leseObjekt1(Objekt1 o1_example);
public abstract Objekt2 leseObjekt2(Objekt2 o2_example);

public boolean pruefeObjekt1(Objekt1 o1) {...}
...
}

public class MySQLManager extends DBManager {...}

Später würde ich das Ganze zB. wie folgt einbinden
DBManager dbm = new MySQLManager(); // bzw.
DBManager dbm = new DB4OManager();
dbm.verbinde(...)
Objekt1 o1 = new Object1("Hallo","Welt");
dbm.schreibeObjekt1(o1);
dbm.trenne();

Für eine relationale Datenbank ist dieses Beispiel ok und funktioniert
super. Ich habe aber noch DB4O und dort passt dann die Methode
verbinde(String host ...) nicht mehr.

1. Wie bekomme ich sowas einheitlich gelöst?
2. Das Model beinhaltet fertige Methoden zum Prüfen der Objekte vor dem
schreiben in die Datenbank, gibt es ein Muster womit man so eine Prüfung
ohne zutun des Entwicklers realisiert? Also das der Entwickler nur die
Methode schreibeObjekt1(...) {...} füllt und das Model halt die Prüfung
vor dem abschicken durchführt. Oder sollte man sowas dem Entwickler
überlassen?

Schonmal vielen Dank

Thomas Chojecki
Jürgen Wille
2008-12-16 16:42:11 UTC
Permalink
Post by Thomas Chojecki
ich will eine Schnittstelle für das Schreiben und Lesen von Objekten in
die Datenbank realisieren.
Da nimmt man besser ein einigermassen ausgereiftes Design, dass auch
viele andere benutzen, also Hibernate, Toplink oder auch OpenJPA. Sowas
selber zu schreiben ist aufwändig, fehleranfällig und erfordert von den
anderen Entwicklern Einarbeitung in Deine Schnittstelle, obwohl sie
sicher teils schon Ahnung von den vorhandenen Implementationen haben.
Wenn Du Dinge wie Transaktionen, Connection-Pooling, Object-Caching,
Relationen zwischen Objekten etc. in Dein Modell einbaust, bist Du immer
noch nicht leistungsfähiger als mit den vorhandenen Lösungen, hast Deiner
Anwendung aber zuverlässig verbaut, in anderen Zusammenhängen nachgenutzt
zu werden.

[..]
Post by Thomas Chojecki
Für eine relationale Datenbank ist dieses Beispiel ok und funktioniert
super. Ich habe aber noch DB4O und dort passt dann die Methode
verbinde(String host ...) nicht mehr.
Da hast Du allerdings bei den bekannten ORM auch ein Problem, für das ich
Dir keine Lösaung sagen kann :-)
Post by Thomas Chojecki
2. Das Model beinhaltet
fertige Methoden zum Prüfen der Objekte vor dem schreiben in die
Datenbank, gibt es ein Muster womit man so eine Prüfung ohne zutun des
Entwicklers realisiert? Also das der Entwickler nur die Methode
schreibeObjekt1(...) {...} füllt und das Model halt die Prüfung vor dem
abschicken durchführt. Oder sollte man sowas dem Entwickler überlassen?
Wenn Du auf einen ORM eine eigene dünne Schicht zum Prüfen aufsetzt,
kannst Du deine zu persistierenden Objekte einfach alle ein Interface
implementieren lassen. Dann kannst Du das Prüfen (ich nehme an hier geht
es nur um sematische Prüfungen) in entsprechende eigene Prüfer auslagern,
die das klassenspezifische erledigen. Welcher Prüfer benutzt wird kannst
Du über Typ-Parameter festlegen.

Gruß Jürgen
Thomas Chojecki
2008-12-17 13:51:51 UTC
Permalink
Post by Jürgen Wille
Post by Thomas Chojecki
ich will eine Schnittstelle für das Schreiben und Lesen von Objekten in
die Datenbank realisieren.
Da nimmt man besser ein einigermassen ausgereiftes Design, dass auch
viele andere benutzen, also Hibernate, Toplink oder auch OpenJPA. [...]
Die Sache ist die, dass es sich hier um eine Hausarbeit handelt mit
mäßigem Umfang :) Ich tendiere gerne immer zur Praxisnähe, aber in dem
Fall würde es die Arbeit schlichtweg sprengen. Vor allem, da die anderen
sich noch recht schwer mit der Thematik tun. Ziel ist es sich mit dem
Datenbankdesign und der Anbindung zu beschäftigen.

ORM stand auch zur Wahl, aber leider konnte ich niemanden überreden sich
damit auseinander zu setzen :)
Post by Jürgen Wille
Post by Thomas Chojecki
2. Das Model beinhaltet
fertige Methoden zum Prüfen der Objekte vor dem schreiben in die
Datenbank, gibt es ein Muster womit man so eine Prüfung ohne zutun des
Entwicklers realisiert? Also das der Entwickler nur die Methode
schreibeObjekt1(...) {...} füllt und das Model halt die Prüfung vor dem
abschicken durchführt. Oder sollte man sowas dem Entwickler überlassen?
Wenn Du auf einen ORM eine eigene dünne Schicht zum Prüfen aufsetzt,
kannst Du deine zu persistierenden Objekte einfach alle ein Interface
implementieren lassen. Dann kannst Du das Prüfen (ich nehme an hier geht
es nur um sematische Prüfungen) in entsprechende eigene Prüfer auslagern,
die das klassenspezifische erledigen. Welcher Prüfer benutzt wird kannst
Du über Typ-Parameter festlegen.
Genau, es geht um semantische Prüfungen ob der Zahlenbereich eingehalten
wurde und der Typ valide ist. In der Datenbank wird es zusätzlich über
Domänen sichergestellt aber für DB4O wäre es zwingend notwendig eine
Javaimprementierung zu bauen. Zudem kann man es ja schon auf
Programmebene sicherstellen.

Ich versteh aber nicht was Du mit dem Interface meinst. Hättest Du da
ggf. ein Knappes Beispiel für mich?
Post by Jürgen Wille
Gruß Jürgen
Besten Dank und schönes Grüße
Thomas
Stefan Ram
2008-12-17 14:20:50 UTC
Permalink
Post by Thomas Chojecki
Die Sache ist die, dass es sich hier um eine Hausarbeit handelt
Es ist nicht klar, ob Hausaufgaben einen Nutzen haben:

http://www.alfiekohn.org/teaching/edweek/homework.htm
http://www.welt.de/wissenschaft/article1621102/1.html
http://blogs.usatoday.com/oped/2006/09/kids_may_be_rig.html

Aber jedenfalls könnten sie schaden, wenn Lehrer allzu
streng auf ihre Bearbeitung achten:

http://www.szon.de/news/politik/vermischtes/200810280554.html

Wenn man durch Hausaufgaben mit fragwürdigen Entwürfen
vertraut gemacht wird, dann wäre es vielleicht wirklich
besser, gar keine Hausaufgaben zu machen. Oder jedenfalls
erst einmal kleinere Brötchen zu backen und Aufgaben zu
behandeln mit denen Lehrer und Schüler nicht überfordert
sind.
Post by Thomas Chojecki
Ziel ist es sich mit dem
Datenbankdesign und der Anbindung zu beschäftigen.
Hier ist es weitaus besser, existierende Schnittstellen, die
von gut ausgebildeten Entwicklern verfaßt wurden, zu erlernen,
als fragwürdige selbstgebastelte Beispiele.

Ich würde da relationale Gestaltung und SQL + JDBC behandeln,
aber auch Hibernate zu behandeln wäre eine Möglichkeit.

Ohne sehr gute Vorkenntnisse gleich von diesen Dingen
abstrahieren zu wollen, ist überambitioniert.
Post by Thomas Chojecki
Genau, es geht um semantische Prüfungen ob der Zahlenbereich
eingehalten wurde und der Typ valide ist.
Ich weiß zwar nicht, was eine »semantische Prüfung« ist,
aber so etwas kann man sicher auch erst einmal an kleineren
Aufgaben lernen.
Thomas Chojecki
2008-12-17 16:24:47 UTC
Permalink
Post by Stefan Ram
Post by Thomas Chojecki
Die Sache ist die, dass es sich hier um eine Hausarbeit handelt
http://www.alfiekohn.org/teaching/edweek/homework.htm
http://www.welt.de/wissenschaft/article1621102/1.html
http://blogs.usatoday.com/oped/2006/09/kids_may_be_rig.html
Aber jedenfalls könnten sie schaden, wenn Lehrer allzu
http://www.szon.de/news/politik/vermischtes/200810280554.html
Wenn man durch Hausaufgaben mit fragwürdigen Entwürfen
vertraut gemacht wird, dann wäre es vielleicht wirklich
besser, gar keine Hausaufgaben zu machen. Oder jedenfalls
erst einmal kleinere Brötchen zu backen und Aufgaben zu
behandeln mit denen Lehrer und Schüler nicht überfordert
sind.
So schlimm ist es noch nicht :) Bis dato tanzte auch eher ein Professor
aus der Rolle und der wurde inzwischen in Pension geschickt. Es werden
uns schon fertige Implementationen beigebracht und uns über das
zerstückeln dieser in kleine, überschaubare Beispiele näher gebracht. So
das wir wissen wann und wieso wir das anwenden sollen. Jetzt mal als
ganz grobes Beispiel Vektoren, Listen und z.B. Bäume. Wann verwendet man
was, wie schaut so eine Struktur aus und wie ist schaut die Komplexität aus.

Was leider versäumt wurde zu unterrichten, ist die Nutzung von
Entwurfsmustern. Alleine die Tatsache das einige Studenten mit Sachen
wie z.B. Interatoren, Collections und weiteren Grundsachen nicht
arbeiten, da sie nicht wissen das es sowas gibt, ist für mich
erschreckend. Man kommt ums Selbststudium nicht herum und wenn man dann
vor ein Problem gestellt wird und sich nie weitergebildet hat, stößt man
schnell an seine Grenzen. Für mich sind solche Hausarbeiten dann der
einzige Weg das Wissen was man so am Rande gesammelt hat, einzusetzen
und zu schauen ob etwas "hängen geblieben" ist. Mir wäre es zumindest
Peinlich später in der Praxis nicht weiter zu kommen oder im Falle von
Entwurfsmustern, nicht zu wissen was andere von mir wollen.
Post by Stefan Ram
Post by Thomas Chojecki
Ziel ist es sich mit dem
Datenbankdesign und der Anbindung zu beschäftigen.
Hier ist es weitaus besser, existierende Schnittstellen, die
von gut ausgebildeten Entwicklern verfaßt wurden, zu erlernen,
als fragwürdige selbstgebastelte Beispiele.
Ich würde da relationale Gestaltung und SQL + JDBC behandeln,
aber auch Hibernate zu behandeln wäre eine Möglichkeit.
Gearbeitet habe ich mit SQL und JDBC und bringe es gerade den anderen im
Crashkurs einigermassen bei. Jeder von ihnen kann SQL, aber keiner hat
jemals mit JDBC gearbeitet.
Post by Stefan Ram
Ohne sehr gute Vorkenntnisse gleich von diesen Dingen
abstrahieren zu wollen, ist überambitioniert.
Ja das ist wahr, aber ein gewisses Ziel muss man sich doch setzten um
hinzuarbeiten. Bin froh das ich damals mein Basiswissen durch Nachhilfe
geben, gestärkt habe und durch das ausarbeiten von erweiterten
Beispielen die nicht direkt in den Vorlesungen beigebracht wurden, auch
eigene Schwächen ausmerzen konnte.
Post by Stefan Ram
Post by Thomas Chojecki
Genau, es geht um semantische Prüfungen ob der Zahlenbereich
eingehalten wurde und der Typ valide ist.
Ich weiß zwar nicht, was eine »semantische Prüfung« ist,
aber so etwas kann man sicher auch erst einmal an kleineren
Aufgaben lernen.
Ich habe mich wohl etwas falsch ausgedrückt. :) Meinte allgemein
Eingabefehler z.B. sind Wertebereiche zu beachten oder bestimmte
Formate. Wobei, sowas kann man direkt in den Objekten lösen beim setzen
der Parameter.

Gruß
Thomas
Stefan Ram
2008-12-17 20:03:32 UTC
Permalink
Es werden uns schon fertige Implementationen beigebracht und
uns über das zerstückeln dieser in kleine, überschaubare
Beispiele näher gebracht.
Das klingt nicht schlecht. Insbesondere soll man ja auch
lernen, Programme zu /lesen/ und nicht nur zu schreiben.
Was leider versäumt wurde zu unterrichten, ist die Nutzung von
Entwurfsmustern. Alleine die Tatsache das einige Studenten mit
Sachen wie z.B. Interatoren, Collections und weiteren
Grundsachen nicht arbeiten, da sie nicht wissen das es sowas
gibt, ist für mich erschreckend.
Ja, aber: In einem bestimmten Zeitrahmen, wie in einem Semester
oder in zwei Semestern kann man auch nicht alles behandeln.

Jemand hat einmal gesagt »Wenn /alles/ wichtig ist, ist /nichts/
wichtig.« und ich würde hinzufügen »Wer in einer Veranstaltung
/alles/ behandeln will, behandelt /nichts/.«

Manchmal kann es richtig sein, Entwurfsmuster erst einmal
außen vor zu lassen. Beispielsweise, wenn erst einmal die
Grundlagen der Sprache erlernt werden sollen und die Zeit
knapp ist.
Für mich sind solche Hausarbeiten dann der einzige Weg das
Wissen was man so am Rande gesammelt hat, einzusetzen und zu
schauen ob etwas "hängen geblieben" ist.
Das kann ich verstehen. Ich würde nur darauf achten, in einer
einzelnen Aufgabe nicht zu viel auf einmal zu prüfen. Man kann
auch mehrere kleine Aufgaben stellen statt einer großen. Es
sollten einige einfache Aufgaben und einige schwierigere
Aufgaben darunter sein. So haben auch Studenten mit geringeren
Kenntnissen die Möglichkeit, wenigstens einige Aufgaben zu
lösen.

Als ich einmal als Lehrbeauftragter an einer Fachhochschule
Studenten unterrichtet habe, sah ich, daß die meisten ihre
Programmieraufgaben von anderen abgeschrieben hatten und sie
mündlich nicht kommentieren konnten. Daraufhin ersetzte ich
die schriftliche Abgabe von Lösungen in meinen
Lehrveranstaltungen durch kurze mündliche Prüfungen von zirka
fünf Minuten Dauer an jedem Termin.

Ich hatte kleine Programmieraufgaben vorbereitet, und wenn ich
zu einem Studenten ging, dann würfelte ich zunächst vor seinen
Augen aus, welche Aufgabe ich ihm stellen würde. Diese Aufgabe
bearbeitete er dann, während ich direkt neben ihm stand, so
daß er nicht abschreiben konnte. Als Ausgleich für diesen
zusätzlichen Streß waren die Aufgaben aber recht einfach und
prüften gerade das Minimalniveau der Veranstaltung.
Thomas Chojecki
2008-12-17 21:01:57 UTC
Permalink
Stefan Ram schrieb:
[...]
Post by Stefan Ram
Post by Thomas Chojecki
Was leider versäumt wurde zu unterrichten, ist die Nutzung von
Entwurfsmustern. Alleine die Tatsache das einige Studenten mit
Sachen wie z.B. Interatoren, Collections und weiteren
Grundsachen nicht arbeiten, da sie nicht wissen das es sowas
gibt, ist für mich erschreckend.
Ja, aber: In einem bestimmten Zeitrahmen, wie in einem Semester
oder in zwei Semestern kann man auch nicht alles behandeln.
Gebe dir da recht, das kann man den Leuten in so einer kurzen Zeit nicht
zumuten, die meisten sind ja erstmal Glücklich die Basics zu verstehen.
Post by Stefan Ram
Jemand hat einmal gesagt »Wenn /alles/ wichtig ist, ist /nichts/
wichtig.« und ich würde hinzufügen »Wer in einer Veranstaltung
/alles/ behandeln will, behandelt /nichts/.«
Hat was :) Steckt schon viel Wahrheit drin.
Post by Stefan Ram
Manchmal kann es richtig sein, Entwurfsmuster erst einmal
außen vor zu lassen. Beispielsweise, wenn erst einmal die
Grundlagen der Sprache erlernt werden sollen und die Zeit
knapp ist.
Für sowas empfehlen sich auch eher Wahlpflichtfächer in höheren
Semestern. Wer es wissen will, der belegt diese. Ab und an ändern sich
die Fächer/Module sogar, so das man z.B. auch mal Fächer aus niedrigeren
oder höheren Semestern belegt. Und wenn man sieht, das Java doch nicht
so das Wahre ist oder das Thema zu abstrakt erscheint, dann nimmt man
halt einen anderen Schwerpunkt.
Post by Stefan Ram
Post by Thomas Chojecki
Für mich sind solche Hausarbeiten dann der einzige Weg das
Wissen was man so am Rande gesammelt hat, einzusetzen und zu
schauen ob etwas "hängen geblieben" ist.
Das kann ich verstehen. Ich würde nur darauf achten, in einer
einzelnen Aufgabe nicht zu viel auf einmal zu prüfen. Man kann
auch mehrere kleine Aufgaben stellen statt einer großen. Es
sollten einige einfache Aufgaben und einige schwierigere
Aufgaben darunter sein. So haben auch Studenten mit geringeren
Kenntnissen die Möglichkeit, wenigstens einige Aufgaben zu
lösen.
Ja das stimmt, die Leute in meiner Gruppe sind schon erstmal mit JDBC
und der implementierung sehr gut bedient. Man (ich) ist bestrebt
bisschen Technik in die Aufgabe einfließen zu lassen, damit man was
mitnimmt. Wenn ich zurückdenke was ich zu meiner anfänglichen
Studienzeit so schönes gezaubert habe, dann sträuben sich mir die Haare
:) Ich frag mich manchmal wie ich einige Sachen zu laufen gebracht habe.
Wild drauf losprogrammiert und wenns nicht lief, eben rumprobiert
(probieren ging über studieren) bis es ging ;) Da haben wir noch Sachen
geändert am Konzept damit es lauffähig war und auch Sachen weggelassen
die wir wegen nem Denkfehler nicht mehr implementieren konnten.
Post by Stefan Ram
Als ich einmal als Lehrbeauftragter an einer Fachhochschule
Studenten unterrichtet habe, sah ich, daß die meisten ihre
Programmieraufgaben von anderen abgeschrieben hatten und sie
mündlich nicht kommentieren konnten. Daraufhin ersetzte ich
die schriftliche Abgabe von Lösungen in meinen
Lehrveranstaltungen durch kurze mündliche Prüfungen von zirka
fünf Minuten Dauer an jedem Termin.
Ich hatte kleine Programmieraufgaben vorbereitet, und wenn ich
zu einem Studenten ging, dann würfelte ich zunächst vor seinen
Augen aus, welche Aufgabe ich ihm stellen würde. Diese Aufgabe
bearbeitete er dann, während ich direkt neben ihm stand, so
daß er nicht abschreiben konnte. Als Ausgleich für diesen
zusätzlichen Streß waren die Aufgaben aber recht einfach und
prüften gerade das Minimalniveau der Veranstaltung.
Interessante Möglichkeit :) Bei uns gibts inzwischen Creditpoints und
wenn die Person die Aufgabe nicht lösen kann bzw. es abschreibt und
nicht erklärt, dann siehts Schwarz aus.

Aber ich wunder mich eh, wieso kaum einer bei uns abschreibt, da wird
dann eher nichts abgegeben anstatt sich die Mühe zu machen.

Finde aber die Möglichkeit das Problem in den Griff zu bekommen mal echt
Innovativ. Vor allem wenn sich der Dozent die Mühe macht es den Leuten
näherzubringen und seinen Beruf mal ernst nimmt.
Stefan Ram
2008-12-16 18:50:47 UTC
Permalink
Post by Thomas Chojecki
eine Schnittstelle für das Schreiben und Lesen von Objekten
- Diese »Schnittstelle« ist nicht mit »interface« deklariert.

- Sie hat geringe Kohäsion, da sie Belange
einer Datenbank und vieler andere Typen vermengt.
Post by Thomas Chojecki
public abstract void verbinde(String host, int port, String db,...);
public abstract void trenne();
public abstract boolean istVerbunden();
- Statt »verbinde« würde man normalerweise einen Konstruktor
verwenden, der dann ein gültiges Verbindungsobjekt
ergibt, das mit »close()« wieder geschlossen wird.

Diese Schnittstelle ist also nicht modular (wie ein
System von Schnittstellen es wäre), sondern monolithisch.

- Die Namen der Einträge sind deutsch.

- Die Schnittstelle muß immer verändert werden, wenn
neue Objekttypen hinzugefügt werden: Ein Verstoß
gegen das Offen-Geschlossen-Prinzip.
Post by Thomas Chojecki
public abstract void schreibeObjekt1(Objekt1 o1);
public abstract void schreibeObjekt2(Objekt1 o2);
- Statt die Möglichkeit der Überladung zu nutzen wird
hier der Methodenname »durchnumeriert«.

- Diese Art der Redundanz mit der »Überladung« von
»schreibeObjekt« sollte eigentlich durch
Überschreiben einer einzigen Signatur in den
jeweiligen Objektklassen erfolgen (Polymorphie).
Damit würde auch erst die Einhaltung des Open-Closed-Prinzips
ermöglicht werden.
Post by Thomas Chojecki
...
- Bestehende Schnittstellen (wie Serializable) werden
nicht genutzt.

- Diese Klassendeklaration ist syntaktisch nicht korrekt
bzw. unbestimmt (wegen »...«) und kann so eigentlich
auch nicht diskutiert werden.

- Schnittstellen sollten einmal festgelegt und dann
unveränderlich sein. Dies sieht eher nach einer Deklaration
aus, die im Laufe des Projekts immer wieder verändert
werden soll.
Thomas Thiele
2008-12-17 09:11:45 UTC
Permalink
    - Schnittstellen sollten einmal festgelegt und dann
      unveränderlich sein.
Sollten.
Werden sie aber in der Praxis nie.
Weil man trotz aller Planung und Glaskugel-in-die-Zukunft-schauen
garantiert irgendwas vergessen hat oder feststellt dass man etwas
anders besser dran ist. (z.B. eine Funktion in zwei Teilfunktionen
aufteilen).

Warum halte ich das für erwähnenswert?

Ganz einfach. Weil beim reinen akademischen Softwareentwurf
sowas dann nicht eingeplant wird. Eine *wirklich* wartungsarme
und bugfixingfreundliche Software minimiert nicht nur die
Notwendigkeit nachträglicher Schnittstellenänderung sondern sieht
auch die Möglichkeit einer leichte und transparenten
Schnittstellenänderungen vor.
Thomas Chojecki
2008-12-17 14:41:56 UTC
Permalink
Post by Stefan Ram
Post by Thomas Chojecki
eine Schnittstelle für das Schreiben und Lesen von Objekten
- Diese »Schnittstelle« ist nicht mit »interface« deklariert.
Mit Schnittstelle meine ich auch nicht direkt "interface", sondern gehe
mehr auf die Bedeutung ein, ein Model zwischen das eigentliche Programm
und die DB zu schmieden.
Post by Stefan Ram
- Sie hat geringe Kohäsion, da sie Belange
einer Datenbank und vieler andere Typen vermengt.
Uff, hoffe ich versteh das nicht falsch, aber durch das abstrakte Model
erzwinge ich doch die starke Kohäsion. Jeder Entwickler erbt von dem
Model und erzeugt eine "Schnittstelle" für die entsprechende Datenbank.
Post by Stefan Ram
Post by Thomas Chojecki
public abstract void verbinde(String host, int port, String db,...);
public abstract void trenne();
public abstract boolean istVerbunden();
- Statt »verbinde« würde man normalerweise einen Konstruktor
verwenden, der dann ein gültiges Verbindungsobjekt
ergibt, das mit »close()« wieder geschlossen wird.
Ok habe ich geändert und das Problem mit den unterschiedlichen
Parametern bei verbinden() hat sich damit auch erledigt.
Post by Stefan Ram
Diese Schnittstelle ist also nicht modular (wie ein
System von Schnittstellen es wäre), sondern monolithisch.
Das wollte ich auch bezwecken. Die Aufgabe ist deutlich gestellt und
soll in Zukunft nicht erweiterbar sein.
Post by Stefan Ram
- Die Namen der Einträge sind deutsch.
Die Vorlage ist ebenfalls deutsch. Ansonsten gebe ich dir recht und
programmiere auch ausschließlich auf englisch.
Post by Stefan Ram
- Die Schnittstelle muß immer verändert werden, wenn
neue Objekttypen hinzugefügt werden: Ein Verstoß
gegen das Offen-Geschlossen-Prinzip.
Die Tabellen sind fest definiert und jede Tabelle ist ein bestimmter
Typ. Erweiterung ist nicht vorgesehen.
Post by Stefan Ram
Post by Thomas Chojecki
public abstract void schreibeObjekt1(Objekt1 o1);
public abstract void schreibeObjekt2(Objekt1 o2);
- Statt die Möglichkeit der Überladung zu nutzen wird
hier der Methodenname »durchnumeriert«.
Es handelt sich ja hier um einen Beispielcode. In Wirklichkeit hat jede
Schreibmethode halt den Tabellennamen. Z.B. sind Tabellen wie Knoten,
Leitung usw. gegeben und die zugehörigen Methoden heißen auch
schreibeKnoten(..) schreibeLeitung(..) usw.
Post by Stefan Ram
- Diese Art der Redundanz mit der »Überladung« von
»schreibeObjekt« sollte eigentlich durch
Überschreiben einer einzigen Signatur in den
jeweiligen Objektklassen erfolgen (Polymorphie).
Damit würde auch erst die Einhaltung des Open-Closed-Prinzips
ermöglicht werden.
Daran habe ich nicht gedacht, habe mir als Muster die ORM-Modelle zur
Hand genommen. Ist es den Sinnvoll auf Überlagern zu setzen? Also bei
dem Beispiel.
Post by Stefan Ram
Post by Thomas Chojecki
...
- Bestehende Schnittstellen (wie Serializable) werden
nicht genutzt.
Wird im Moment nicht gebraucht und ich muss ehrlich gestehen, hatte mit
Serializable noch nichts am Hut gehabt und müsste mich da einlesen was
für Vorzüge es bringt.
Post by Stefan Ram
- Diese Klassendeklaration ist syntaktisch nicht korrekt
bzw. unbestimmt (wegen »...«) und kann so eigentlich
auch nicht diskutiert werden.
Das kompletten abstrakte Model mit etwa 80 Zeilen Code, wollte ich jetzt
nicht unbedingt publizieren, da die Methodenköpfe sich nur minimal
unterschieden. Ich wollte nur zeigen, das es mehr als eine Methode zum
schreiben, lesen gibt. Löschen soll auch möglich sein, aber das kann man
ja erweitern und spielt bei der eigentlichen Frage zum Modell im Moment
keine Rolle
Post by Stefan Ram
- Schnittstellen sollten einmal festgelegt und dann
unveränderlich sein. Dies sieht eher nach einer Deklaration
aus, die im Laufe des Projekts immer wieder verändert
werden soll.
Wie würde es den in der Praxis aussehen? Es soll ja ein ORM darstellen.
Christoph Herrmann
2008-12-17 14:51:54 UTC
Permalink
Post by Thomas Chojecki
Uff, hoffe ich versteh das nicht falsch, aber durch das abstrakte Model
erzwinge ich doch die starke Kohäsion. Jeder Entwickler erbt von dem
Model und erzeugt eine "Schnittstelle" für die entsprechende Datenbank.
Bei dir ist alles zusammen in einer Klasse und somit unweigerlich
verbunden. Man kann nicht einzelne Teile getrennt voneinander erweitern
oder umtauschen.
Post by Thomas Chojecki
Daran habe ich nicht gedacht, habe mir als Muster die ORM-Modelle zur
Hand genommen. Ist es den Sinnvoll auf Überlagern zu setzen? Also bei
dem Beispiel.
"Überlagern" kenne ich nicht, aber "Überladen" meinst du sicher. Wäre in
deinem Falle empfehlenswert, daher statt:

schreibeKnoten(Knoten knoten) {}
schreibeLeitung(Leitung leitung) {}

wäre folgendes empfehlenswert:

schreibe(Knoten knoten) {}
schreibe(Leitung leitung) {}

Das macht das API auch etwas stabiler gegenüber neuen Klassen.
Äquivalent dazu würde ich es auch bei deinen Prüfmethoden machen.
Post by Thomas Chojecki
Das kompletten abstrakte Model mit etwa 80 Zeilen Code, wollte ich jetzt
nicht unbedingt publizieren, da die Methodenköpfe sich nur minimal
unterschieden. Ich wollte nur zeigen, das es mehr als eine Methode zum
schreiben, lesen gibt. Löschen soll auch möglich sein, aber das kann man
ja erweitern und spielt bei der eigentlichen Frage zum Modell im Moment
keine Rolle
Wie wäre es mit einer Basisklasse und für jede Tabelle eine abgeleitete
Klasse? Statt alle verschiedenen Tabellen durch verschiedene Methoden in
der gleichen Klasse zu unterscheiden. Würde es einfacher machen zu
erweitern.
Post by Thomas Chojecki
Wie würde es den in der Praxis aussehen? Es soll ja ein ORM darstellen.
Schau dir doch die in der Praxis verwendeten ORM an.
--
Mit freundlichen Grüßen,
Christoph Herrmann

http://dragonprojects.de/
Thomas Chojecki
2008-12-17 16:54:52 UTC
Permalink
Post by Christoph Herrmann
"Überlagern" kenne ich nicht, aber "Überladen" meinst du sicher. Wäre in
Komme damit selber durcheinander :) Habe jetzt mal im Script
nachgeblättert und wir haben es wie folgt gelernt, bzw. sollten es
lernen: :)

Überladen:
void doSomething(int i) { ... }
void doSomething(String s) { ...}
void doSomething(int i, String s) { ... }

Also das was du meintest.

Überlagern (laut Eclipse "Override" genannt):
Kommt durch Vererbung zustande.

class A {
void doSomething(int i) { ... }
void doSomething(String s) { ... }
}
class B extends A {
void doSomething(int i) { ... }
}

Gehört in dem Fall dann nicht zum Thema :) Da keine existierenden
Methoden überlagert werden außer halt die abstrakten Methoden.
Post by Christoph Herrmann
Das macht das API auch etwas stabiler gegenüber neuen Klassen.
Äquivalent dazu würde ich es auch bei deinen Prüfmethoden machen.
Sieht in meinen Augen auch im Code einleuchtender aus, ich frage mich
aber immer noch, wieso es bei ORM nicht so gemacht wird. Das gleiche bei
Settern und Gettern. Das ist auch der Grund, weshalb ich das als
schreibeLeitung() und schreibeKnoten() umgesetzt habe.

Mir fallen folgende Punkte gegen das überladen ein:
- lesbarkeit beim verwenden der Klasse für aussenstehende. (z.B. wenn
man mit Eclipse schaut, welche Methoden zur verfügung stehen.
- Wie sieht es bei vererbung aus? Und ich glaube das wäre auch der
Punkt. Nimmt man z.B. die beiden oberen Klassen A und B.

void doSomething(A i) { ... }
void doSomething(B i) { ... }

Ohne Gewähr.
Post by Christoph Herrmann
Post by Thomas Chojecki
Das kompletten abstrakte Model mit etwa 80 Zeilen Code, wollte ich jetzt
nicht unbedingt publizieren, da die Methodenköpfe sich nur minimal
unterschieden. Ich wollte nur zeigen, das es mehr als eine Methode zum
schreiben, lesen gibt. Löschen soll auch möglich sein, aber das kann man
ja erweitern und spielt bei der eigentlichen Frage zum Modell im Moment
keine Rolle
Wie wäre es mit einer Basisklasse und für jede Tabelle eine abgeleitete
Klasse? Statt alle verschiedenen Tabellen durch verschiedene Methoden in
der gleichen Klasse zu unterscheiden. Würde es einfacher machen zu
erweitern.
Jede Tabelle ist ein eigener Typ, würde dann wie folgt aussehen.

abstract class Typ {
abstract void schreibe();
abstract void lese();
}

class Leitung extends Typ {
void schreibe() {
???
JDBC
DB4O
}
void lese() { ... }
}

Bekomme so die Trennung bei den Typen nicht bei den Datenbanken.
Post by Christoph Herrmann
Post by Thomas Chojecki
Wie würde es den in der Praxis aussehen? Es soll ja ein ORM darstellen.
Schau dir doch die in der Praxis verwendeten ORM an.
Die bauen ähnlich auf wie mein DBManager. Diese sind aber auch für
relationale Datenbanken entworfen worden. Für Objektorientierte ist da
keine mir bekannte Lösung.
Christoph Herrmann
2008-12-17 20:56:18 UTC
Permalink
Post by Thomas Chojecki
Sieht in meinen Augen auch im Code einleuchtender aus, ich frage mich
aber immer noch, wieso es bei ORM nicht so gemacht wird. Das gleiche bei
Settern und Gettern. Das ist auch der Grund, weshalb ich das als
schreibeLeitung() und schreibeKnoten() umgesetzt habe.
Womöglich weil es nicht möglich ist:

class Point
{
private int x;
private int y;
}

Wie willst du per überladene Methoden die Setter für beide Attribute
implementieren?

Viel schwieriger wird es noch beim Getter. Diese sind Parameterlos.
Selbst wenn der Datentyp der Attribute verschieden wäre, betrifft dies
nur die Rückgabewerte, daher ist keine Überladung möglich.
Post by Thomas Chojecki
- lesbarkeit beim verwenden der Klasse für aussenstehende. (z.B. wenn
man mit Eclipse schaut, welche Methoden zur verfügung stehen.
Ich weiß jetzt nicht genau ob Eclipse es genau so macht, aber beim
Visual Studio kann ich die verschiedenen überladene Methoden durchgehen.
Bei Eclipse ist dies glaube ich ebenso. Also kein Kritikpunkt.
Post by Thomas Chojecki
- Wie sieht es bei vererbung aus? Und ich glaube das wäre auch der
Punkt. Nimmt man z.B. die beiden oberen Klassen A und B.
void doSomething(A i) { ... }
void doSomething(B i) { ... }
Ohne Gewähr.
Bei Vererbung sieht es wie folgt aus:
- Ist die Methode in Oberklasse vorhanden und die Signatur gleich, dann
wird die Methode überschrieben
- Unterscheidet sich die Signatur wird die Methode überladen
Post by Thomas Chojecki
Jede Tabelle ist ein eigener Typ, würde dann wie folgt aussehen.
abstract class Typ {
abstract void schreibe();
abstract void lese();
}
class Leitung extends Typ {
void schreibe() {
???
JDBC
DB4O
}
void lese() { ... }
}
Die schreibe/lese Methoden könntest du in der Basisklasse
implementieren. Wenn die Methode weiß welche Spalten die Tabelle haben,
kann diese die Statements selbst zusammen bauen. Eine Implementierung
beider Methoden in den abgeleiteten Klassen ist somit nicht nötig.

Des weiteren könnte man die Tabellenklassen und die
Datenbankschnittstelle trennen, sodass ein Objekt einer Tabellenklasse
zum Schreiben/Lesen an ein Objekt einer Datenbankschnittstelle
übergibst. Beie sollten dann fest definierte Schnittstellen
implementieren sodass diese beliebig austauschbar sind.

Schemenhaft in etwa:

ExampleTable table = new ExampleTable();
...
JdbcAdapter adapter = new JdbcAdapter("host", ...);
adapter.store(table);
Post by Thomas Chojecki
Die bauen ähnlich auf wie mein DBManager. Diese sind aber auch für
relationale Datenbanken entworfen worden. Für Objektorientierte ist da
keine mir bekannte Lösung.
Das hat einen sehr einfachen Grund. ORM = Object-Relational Mapping,
also Objekte auf eine relationale Datenbank mappen. Für
Objektdatenbanken ist kein ORM nötig, da die Objekte nicht auf die
relationale Struktur angepasst werden müssen sondern direkt gespeichert
werden.

Warum sollte also ein ORM, der nur für relationale Datenbanken Sinn
macht Objektdatenbanken unterstützen?
--
Mit freundlichen Grüßen,
Christoph Herrmann

http://dragonprojects.de/
Thomas Chojecki
2008-12-17 21:33:22 UTC
Permalink
Post by Christoph Herrmann
Post by Thomas Chojecki
Sieht in meinen Augen auch im Code einleuchtender aus, ich frage mich
aber immer noch, wieso es bei ORM nicht so gemacht wird. Das gleiche bei
Settern und Gettern. Das ist auch der Grund, weshalb ich das als
schreibeLeitung() und schreibeKnoten() umgesetzt habe.
class Point
{
private int x;
private int y;
}
Wie willst du per überladene Methoden die Setter für beide Attribute
implementieren?
Ist mir kurz nach dem schreiben dann auch aufgefallen. Ich brauch wohl
langsam eine Pause.

[...]
Post by Christoph Herrmann
Ich weiß jetzt nicht genau ob Eclipse es genau so macht, aber beim
Visual Studio kann ich die verschiedenen überladene Methoden durchgehen.
Bei Eclipse ist dies glaube ich ebenso. Also kein Kritikpunkt.
Ja, wird auch so wie beschrieben angezeigt.

[...]
Post by Christoph Herrmann
- Ist die Methode in Oberklasse vorhanden und die Signatur gleich, dann
wird die Methode überschrieben
- Unterscheidet sich die Signatur wird die Methode überladen
Die Frage war auf das untere Beispiel bezogen und im nachhinein überlüssig.

[meinen komischen Code beseitigt]
Post by Christoph Herrmann
Die schreibe/lese Methoden könntest du in der Basisklasse
implementieren. Wenn die Methode weiß welche Spalten die Tabelle haben,
kann diese die Statements selbst zusammen bauen. Eine Implementierung
beider Methoden in den abgeleiteten Klassen ist somit nicht nötig.
Das verstößt doch gegen ein Konzept ... Wiederverwendbarkeit?
Post by Christoph Herrmann
Des weiteren könnte man die Tabellenklassen und die
Datenbankschnittstelle trennen, sodass ein Objekt einer Tabellenklasse
zum Schreiben/Lesen an ein Objekt einer Datenbankschnittstelle
übergibst. Beie sollten dann fest definierte Schnittstellen
implementieren sodass diese beliebig austauschbar sind.
Ist ja derzeit so gemacht. Aber nicht über das Überladen gelöst.
Post by Christoph Herrmann
ExampleTable table = new ExampleTable();
...
JdbcAdapter adapter = new JdbcAdapter("host", ...);
adapter.store(table);
Meins sieht im Moment so aus

public abstract class DBManager {

public abstract void trennen();
public abstract boolean istVerbunden();

public abstract void schreibe(Knoten k);
public abstract void schreibe(Leitung l);

public abstract Knoten leseKnoten();
public abstract Leitung leseLeitung();

public boolean pruefe(...) {...}
}

Ist jetzt wieder nur kurz gehalten.
Verbindung wird über Konstruktor der geerbten Klasse aufgebaut.
Post by Christoph Herrmann
Post by Thomas Chojecki
Die bauen ähnlich auf wie mein DBManager. Diese sind aber auch für
relationale Datenbanken entworfen worden. Für Objektorientierte ist da
keine mir bekannte Lösung.
Das hat einen sehr einfachen Grund. ORM = Object-Relational Mapping,
also Objekte auf eine relationale Datenbank mappen. Für
Objektdatenbanken ist kein ORM nötig, da die Objekte nicht auf die
relationale Struktur angepasst werden müssen sondern direkt gespeichert
werden.
Warum sollte also ein ORM, der nur für relationale Datenbanken Sinn
macht Objektdatenbanken unterstützen?
Ja die Bedeutung von ORM ist mir bekannt :) Ich meinte eher eine Lösung
die halt eine Datenbankschnittstelle zur verfügung stellt für Objekt-
sowie Relationale-Datenbanken. Ich versuch ja nicht direkt ein ORM
nachzumodelieren.
Bernd Hohmann
2008-12-17 22:39:05 UTC
Permalink
Post by Thomas Chojecki
class Leitung extends Typ {
void schreibe() {
???
JDBC
DB4O
}
void lese() { ... }
}
Bekomme so die Trennung bei den Typen nicht bei den Datenbanken.
Nur um das mal wieder auf den Boden der Praxis zu bringen:

Es gibt keine "Universaldatenbankschnittstelle" und jeglicher Versuch,
das in irgendeiner Form im Vorfeld (!) zu organisieren führt zu erst zu

1) absonderlichen, unwartbaren Konstruktionen

2) dann zur Abstrahierung und Generalisierung (statt SQL muss man sich
zusätzlich mit einer noch absonderlicheren Konstruktion oder
Programmiersprachenersatz herumschlagen)

3) zum Schluss entweder zu Rekordumsätzen bei den Hardwareherstellern
oder einem kompletten Redesign der Anwendung weil es nicht mehr skaliert.

Ich stell hier gerade eine Anwendung von DB2 nach MySQL um und muss an
so einigen Stellen nicht nur die Queries komplett umbauen sondern auch
die Speicherkonzepte weil die DB2 so einige Bequemlichkeiten hatte, die
MySQL nicht hergibt - dafür ist MySQL wesentlich flinker an anderen
Stellen hat sodass ich mir statt einer 28zeiligen Query sogar eine
Rückverlagerung in Java-Code leisten kann.

Daher schreibe Dein Datenbankinterface erstmal primär für eine Klasse
von Datenbanken. Entweder Relational wie DB2,MySQL etc oder
Objektorientiert wie DB4O

Dann entscheide Dich für eine Datenbank

Dann für eine Version und am besten noch gleich für einen Revisionstand
den Du möglichst lange beibehalten kannst.
Post by Thomas Chojecki
Für eine relationale Datenbank ist dieses Beispiel ok und funktioniert
super. Ich habe aber noch DB4O und dort passt dann die Methode
verbinde(String host ...) nicht mehr.
1. Wie bekomme ich sowas einheitlich gelöst?
Erfinde analog zu java.sql.Connection ein "de.chojecki.DBConnection"
welche die Connectionobjects von SQL und DB4O enthält. Gegebenenfalls
als Object durchreichen und dann mit "instanceof" prüfen, was gerade
aktiv ist.

Du musst eh für jeden Prozess eine eigene Connection zurückliefern.

Beschwerden wegen Performance bitte nicht an mich.
Post by Thomas Chojecki
2. Das Model beinhaltet fertige Methoden zum Prüfen der Objekte vor dem
schreiben in die Datenbank, gibt es ein Muster womit man so eine Prüfung
ohne zutun des Entwicklers realisiert?
Lass es.

Dokumentiere nur die Fehler "ok, einfügen/überschreiben hat geklappt,
leseoperation erfolgreich". Alles andere ist entweder ein Fehler im SQL,
Connection lost oder Datenbank im Eimer.

Viele Modelle vergessen (oder haben es erst nachträglich eingefummelt),
dass eine anwenderfreundliche Programmierung verlangt, möglichst früh
auf einen Fehler hinzuweisen.

Das sind zb. Constraints auf Feldebene (Muss grösser Null sein, darf nur
Ziffern enthalten, Mailadresse muss bestimmten Kriterien entsprechen),
dann gehts auf Seitenebene weiter (ist der Datensatz insich stimmig) und
ggf. auf Applikationsebene (zb. Lohnabrechnungen müssen eigentlich nach
der Erfassung der Stamm-,Lohn- und sonstigen Daten einen
Integritätscheck der aktuellen Erfassung gegen die gesetzlichen
Bestimmungen machen).

Das ins Datenbankmodul zu packen ist eigentlich viel zu spät.

Ich habe einen minimalen Wrapper für SQL geschrieben, der mir in den
letzten 3 Jahren (nach 7 Jahren auf dem gleichen Schlingerkurs wie Du)
viel Freude bereitet hat:

1) Eine Mutterklasse, die sich beim Start von der Datenbank die
Tabellenbeschreibung holt wenn sie nicht händisch definiert wurde (da
geht es schon los zwischen DB2 und MySQL) und danach versucht, anhand
eines vorgegebenen Bennenungschemas die Tabellenspalten auf die
Variablen der Subklassen zu verteilen (incl. identifikation der
Primärkeys die dann auch entsprechend heissen). strDB_PK_CUSTNB ist dann
ein Primärkey vom Typ String der eine Kundennummer enthält.

2) Zugriff auf die Tabelle geht dann zb. so:

ddCustomer.strDB_PK_CUSTNB = "4711";
if (ddCustomer.dbRead())
System.out.println("Found: name=" + ddCustimer.strDB_Name1);

3) Paar Routinen wie dbREAD(), dbWRITE(), dbUPDATE() die
Standardvorgänge übernehmen über automatisch generierte Queries.

4) Und dazu ganz banal und platt Routinen wie
dbReadAllMaintainersForMachineSerialNumber(String strSN) die über die
Datenbankklasse für die Betreuer ein Array der Betreuernummern
zurückliefert.

Ich gebe zu: es ist krude, blöd und gerade die Mutterklasse ist
verstopft mit vielen if und switches um die paar Datenbanken zu handeln
die wir je nach Verwendung im Einsatz haben.

Aber glaube mir, dass wir für die eleganteren Lösungen der reinen Lehre
sehr viel Schmerzens/Lehrgeld bezahlt haben weil sie entweder sehr
Pflegebedürftig waren (neben dem Applikationscode musste man auch sehr
tief in den hochkomplexen Access-Modulen nachpatchen - obwohl man das
eigentlich nie mehr anfassen wollte) oder einen enormen
Dokumentationsaufwand über weitere Tools nachsich zog.

So haben wir es im Moment sehr einfach: man landet irgendwo auf einem
ddDict_globKrankenkassen.getKKforEmployee(...) und landet dann im
Debugger direkt ohne Umschweife und Reflectionscherze an der Stelle, wo
die DB abgefragt wird - das ist besonders dann sehr hilfreich, wenn man
gerade an paar sehr viele Kunden was ausgeliefert hat und es doch nicht
läuft wärend das Finanzamt mit Verzugszinsen droht.

Bernd

PS: Wenn Du das durchziehst, dann sorge dafür dass jede Datenbankklasse
einen verwertbaren Status via .toString() abliefert.

Danke
--
Well, there's egg and bacon; egg sausage and bacon; egg and
***@spamonly.de ; egg bacon and spam; egg bacon sausage
and ***@spamonly.net ; spam bacon sausage and spam;spam
egg spam spam bacon and ***@nixwill.de ; spam sausage
Thomas Thiele
2008-12-18 00:08:34 UTC
Permalink
Post by Christoph Herrmann
"Überlagern" kenne ich nicht, aber "Überladen" meinst du sicher.
Ja. Das meint er.

Java kennt kein Verdecken ("überlagern").
Stefan Ram
2008-12-17 20:31:05 UTC
Permalink
Post by Thomas Chojecki
Post by Stefan Ram
- Sie hat geringe Kohäsion, da sie Belange
einer Datenbank und vieler andere Typen vermengt.
Uff, hoffe ich versteh das nicht falsch, aber durch das abstrakte Model
erzwinge ich doch die starke Kohäsion. Jeder Entwickler erbt von dem
Model und erzeugt eine "Schnittstelle" für die entsprechende Datenbank.
Der Begriff »Kohäsion« bezeichnet die inhaltliche
Zusammengehörigkeit der verschiedenen Signaturen eines Typs.
Die Kohäsion kann also nicht durch willkürliche
Zusammenfassung von Signaturen »erzwungen« werden. Siehe auch

http://en.wikipedia.org/wiki/Single_responsibility_principle
http://en.wikipedia.org/wiki/Cohesion_(computer_science)
http://www.davidhayden.com/blog/dave/archive/2004/12/10/680.aspx
Post by Thomas Chojecki
Ist es den Sinnvoll auf Überlagern zu setzen?
Wenn die Methodennamen von Signaturen die »gleiche« Bedeutung
haben, wie etwa bei »println(java.lang.Object)« und
»println(java.lang.String)«, aber nicht, wenn sie
unterschiedliche Bedeutungen haben, wie etwa bei »equals« und
»toString«.
Post by Thomas Chojecki
Post by Stefan Ram
- Schnittstellen sollten einmal festgelegt und dann
unveränderlich sein. Dies sieht eher nach einer Deklaration
aus, die im Laufe des Projekts immer wieder verändert
werden soll.
Wie würde es den in der Praxis aussehen? Es soll ja ein ORM darstellen.
Da bin ich etwas behindert, da ich gar kein Freund von ORMs bin.
Aber ich würde sagen, wenn es schon ein ORM sein muß, dann sollte
man sich an der Gestaltung von verbreiteten Systemen, wie
Hibernate, orientieren. Noch besser wäre es, solche Systeme zu
verwenden, anstatt das Rad neu zu erfinden. Auch dann gibt es
ja noch genug Raum für Übungsaufgaben.
Thomas Chojecki
2008-12-17 21:54:04 UTC
Permalink
Post by Stefan Ram
Post by Thomas Chojecki
Post by Stefan Ram
- Sie hat geringe Kohäsion, da sie Belange
einer Datenbank und vieler andere Typen vermengt.
Uff, hoffe ich versteh das nicht falsch, aber durch das abstrakte Model
erzwinge ich doch die starke Kohäsion. Jeder Entwickler erbt von dem
Model und erzeugt eine "Schnittstelle" für die entsprechende Datenbank.
Der Begriff »Kohäsion« bezeichnet die inhaltliche
Zusammengehörigkeit der verschiedenen Signaturen eines Typs.
Die Kohäsion kann also nicht durch willkürliche
Zusammenfassung von Signaturen »erzwungen« werden. Siehe auch
http://en.wikipedia.org/wiki/Single_responsibility_principle
http://en.wikipedia.org/wiki/Cohesion_(computer_science)
http://www.davidhayden.com/blog/dave/archive/2004/12/10/680.aspx
Höre ich zum Ersten mal, und werde mir es auch gleich mal zu gemühte
nehmen :)
Post by Stefan Ram
Post by Thomas Chojecki
Ist es den Sinnvoll auf Überlagern zu setzen?
Wenn die Methodennamen von Signaturen die »gleiche« Bedeutung
haben, wie etwa bei »println(java.lang.Object)« und
»println(java.lang.String)«, aber nicht, wenn sie
unterschiedliche Bedeutungen haben, wie etwa bei »equals« und
»toString«.
Die Beispiele der Vorredner haben mir inzwischen schon recht viel
geholfen auf dem Weg zum Verständnis.
Post by Stefan Ram
Post by Thomas Chojecki
Post by Stefan Ram
- Schnittstellen sollten einmal festgelegt und dann
unveränderlich sein. Dies sieht eher nach einer Deklaration
aus, die im Laufe des Projekts immer wieder verändert
werden soll.
Wie würde es den in der Praxis aussehen? Es soll ja ein ORM darstellen.
Da bin ich etwas behindert, da ich gar kein Freund von ORMs bin.
Aber ich würde sagen, wenn es schon ein ORM sein muß, dann sollte
man sich an der Gestaltung von verbreiteten Systemen, wie
Hibernate, orientieren. Noch besser wäre es, solche Systeme zu
verwenden, anstatt das Rad neu zu erfinden. Auch dann gibt es
ja noch genug Raum für Übungsaufgaben.
Habe gemerkt das ich mein System fälschlicherweise als ORM bezeichne was
es ja nicht ist. Das Rad neu zu erfinden wäre unvorteilhaft, vor allem
für eine reine relationale Datenbanklösung, was es nicht ist. Den Leuten
Hibernate an den Kopf zu werfen wäre für einige die schon mit JDBC
überfordert sind, ein Genickbruch. Mit einer reinen JDBC Lösung sind sie
somit noch in ihren SQL Gefilden und nicht ganz so Fremd.

Das Thema ist geteilt in 1) Relationale 2) Objektrelationale 3)
Objektorientierte 4) "XML" glaub ich ... Datenbanken.
Jede Person soll sich einen DB Typen aussuchen und diesen Umsetzten.

Unter 1) steht der Klassiker MySQL 2) Postgres mit PostGIS Plugin 3)
DB4O und Hibernate.

Die Wahl für DB4O fiel auf die Leichtigkeit und den sehr starken Bezug
an das Objektorientierte Programmieren. Alternativ wäre Hibernate drine,
aber die Zeit will ich nicht Opfern um mich einzuarbeiten, da ich mir
vorgenommen habe das Modell aufzubauen.

Auf die Frage ob jemand anders lust hat sich in Hibernate einzuarbeiten
kam nur "Neee bitte nicht, hab gehört das soll schwer sein. Der ... hat
seine Hibernatearbeit erst vor kurzem in den Sand gesetzt."

Mindestvoraussetzung für die Abgabe ist eine DB aus dem 1er oder 2er
Bereich, sowie eine aus dem 3er oder 4er Bereich.
Christoph Herrmann
2008-12-17 08:08:33 UTC
Permalink
Post by Thomas Chojecki
Hallo NG,
Hi,
Post by Thomas Chojecki
ich will eine Schnittstelle für das Schreiben und Lesen von Objekten in
die Datenbank realisieren.
zusätzlich zu Stefans Anmerkungen sei dir den Tipp gegeben dich erstmal
mehr mit API Design auseinander zu setzen. Das Buch "Entwurfsmuster von
Kopf bis Fuß" dürfte ganz interessant für dich sein.

Des Weiteren empfehle ich dir schon vorhandene Lösungen anzuschauen und
dahingehend zu prüfen, ob diese deine Anforderungen erfüllen. Nur wenn
dies nicht der Fall ist würde eine eigene Lösung erforderlich sein und
auch dann würde ich mich an schon vorhandene Lösungen orientieren.

Noch Anmerkungen zu deinem Datenbankmanager:

- ORM wäre als Kategorie passender als Datenbankmanager

- Du solltest den ORM in Schichten aufsetzen, eine Schicht wäre die
Abstraktion der Datenbankverbindung, die zweite Schicht für die
Objektspeicherung setzt darauf auf. Die Schicht der Prüfungen würde ich
ebenfalls auslagern. Auf diese Weise ist es weitaus flexibler und du
könntest für einzelne Schichten schon vorhandene Lösungen nehmen (zum
Beispiel JDBC für Datenbankabstraktion)

- Vor allem solltest du nicht versuchen alles in eine Klasse zu
packen... Eine Klasse sollte in der Regel eine Verantwortung haben und
wo es sinnvoll ist durch Objekte bestimmter Schnittstellen erweiterbar
sein bzw. selbst eine Schnittstelle implementieren um austauschbar zu sein
--
Mit freundlichen Grüßen,
Christoph Herrmann

http://dragonprojects.de/
Thomas Chojecki
2008-12-17 14:59:26 UTC
Permalink
Post by Christoph Herrmann
Post by Thomas Chojecki
Hallo NG,
Hi,
Post by Thomas Chojecki
ich will eine Schnittstelle für das Schreiben und Lesen von Objekten in
die Datenbank realisieren.
zusätzlich zu Stefans Anmerkungen sei dir den Tipp gegeben dich erstmal
mehr mit API Design auseinander zu setzen. Das Buch "Entwurfsmuster von
Kopf bis Fuß" dürfte ganz interessant für dich sein.
Habe ich schon in der Freizeit angefangen zu lesen. Kam aber erst zum 3
Muster. Ansonsten ein Klasse Buch, falls hier jemand mit ließt und sich
ebenfalls für Entwurfsmuster interessiert :)
Post by Christoph Herrmann
Des Weiteren empfehle ich dir schon vorhandene Lösungen anzuschauen und
dahingehend zu prüfen, ob diese deine Anforderungen erfüllen. Nur wenn
dies nicht der Fall ist würde eine eigene Lösung erforderlich sein und
auch dann würde ich mich an schon vorhandene Lösungen orientieren.
Ich habe mir einige ORM Modelle angeschaut und diese sind für die
Aufgabe einfach zu komplex aufgebaut. Die Modelle die ich gesehen habe,
setzten voraus das man die Datenbank beschreibt und sich daraus den Code
erzeugen lässt. Bei mir handelt es sich um stolze drei Tabellen die fest
definiert sind. Vielleicht liege ich ja mit dem Gedanken falsch, aber es
scheint einfach zu überdimensioniert zu sein.
Post by Christoph Herrmann
- ORM wäre als Kategorie passender als Datenbankmanager
Ja, das Kürzel ORM trift es auf den Punkt.
Post by Christoph Herrmann
- Du solltest den ORM in Schichten aufsetzen, eine Schicht wäre die
Abstraktion der Datenbankverbindung, die zweite Schicht für die
Objektspeicherung setzt darauf auf. Die Schicht der Prüfungen würde ich
ebenfalls auslagern. Auf diese Weise ist es weitaus flexibler und du
könntest für einzelne Schichten schon vorhandene Lösungen nehmen (zum
Beispiel JDBC für Datenbankabstraktion)
Werde ich mich gleich mal einlesen. Gibt es irgendwie eine Bezeichnung
für dieses Schichtenmodell, so das ich mir da über Google bzw. über
Bücher das wissen aneignen könnte. Bis jetzt schwirrt mir nur DAO und
ORM durch den Kopf. Zu DAO finde ich aber ausser einem Wiki Artikel so
gut wie garnichts. Büchertechnisch komme ich leider auch nicht ran, da
wir zu dem Thema nichts im Verleih haben.
Post by Christoph Herrmann
- Vor allem solltest du nicht versuchen alles in eine Klasse zu
packen... Eine Klasse sollte in der Regel eine Verantwortung haben und
wo es sinnvoll ist durch Objekte bestimmter Schnittstellen erweiterbar
sein bzw. selbst eine Schnittstelle implementieren um austauschbar zu sein
Ok also atomar gestalten.

Mir fehlt im Endeffekt das Wissen zum richtigen Designen und ich weiß
nicht wo ich anfangen soll mir dieses Wissen anzueignen. Es wurde uns
leider nicht vermittelt bzw. die Personen die uns das Wissen vermitteln
sollten, hatten schlicht weg, selber keine Ahnung.
Christoph Herrmann
2008-12-17 15:33:47 UTC
Permalink
Post by Thomas Chojecki
Ich habe mir einige ORM Modelle angeschaut und diese sind für die
Aufgabe einfach zu komplex aufgebaut. Die Modelle die ich gesehen habe,
setzten voraus das man die Datenbank beschreibt und sich daraus den Code
erzeugen lässt. Bei mir handelt es sich um stolze drei Tabellen die fest
definiert sind. Vielleicht liege ich ja mit dem Gedanken falsch, aber es
scheint einfach zu überdimensioniert zu sein.
ORM ist nun mal ein recht komplexe Angelegenheit. Verschiedene
Datenbanken, verschiedene Datentypen, verschiedene Beziehungen zwischen
Tabellen usw. muss ja alles berücksichtigt werden.
Post by Thomas Chojecki
Post by Christoph Herrmann
- ORM wäre als Kategorie passender als Datenbankmanager
Ja, das Kürzel ORM trift es auf den Punkt.
Als Übungsaufgabe halte ich einen ORM für unangebracht, weil es einfach
viel zu komplex ist wenn man es richtig machen will.

Sicher dass nicht nur ein Design für eine Datenbankabstraktion like JDBC
gefragt ist? Das halte ich zum Beispiel für ein schöneres Beispiel, da
man eine solche Abstraktion mit recht wenig Aufwand hin bekommt (wenn
man nicht gerade alle Einstellungsoptionen etc. berücksichtigen muss).
Post by Thomas Chojecki
Werde ich mich gleich mal einlesen. Gibt es irgendwie eine Bezeichnung
für dieses Schichtenmodell, so das ich mir da über Google bzw. über
Bücher das wissen aneignen könnte. Bis jetzt schwirrt mir nur DAO und
ORM durch den Kopf. Zu DAO finde ich aber ausser einem Wiki Artikel so
gut wie garnichts. Büchertechnisch komme ich leider auch nicht ran, da
wir zu dem Thema nichts im Verleih haben.
Es sind einfach mehrere Klassen die zusammenarbeiten. Ich würde einfach
das angesprochene Buch weiterlesen, ich glaube Strategie und
Kompositemuster dürfte hilfreich für dich sein. Für die Prüfklassen
vielleicht Dekorator.
Post by Thomas Chojecki
Mir fehlt im Endeffekt das Wissen zum richtigen Designen und ich weiß
nicht wo ich anfangen soll mir dieses Wissen anzueignen. Es wurde uns
leider nicht vermittelt bzw. die Personen die uns das Wissen vermitteln
sollten, hatten schlicht weg, selber keine Ahnung.
Das Buch ist ein sehr guter Anfang. Entwurfsmuster werden vielfach
verwendet und das Wissen über diese erspart einem sehr viel Denkarbeit.
Da denkt man zum Beispiel "ich bräuchte eine Klasse von der nur eine
Instanz existieren darf, ahh ich nehme ein Singleton".

Der Rest ist denk ich einfach Erfahrung. Man sollte aber mit seinen
Beispielen auf einem überschaubarem Niveau bleiben. Ein ORM halte ich da
für zu komplex um es einfach mal als Beispiel umzusetzen. Wäre ja so als
würde man Excel nachprogrammieren um zu lernen wie eine GUI aufgebaut
wird. :)
--
Mit freundlichen Grüßen,
Christoph Herrmann

http://dragonprojects.de/
Thomas Thiele
2008-12-17 09:13:05 UTC
Permalink
Post by Thomas Chojecki
ich will eine Schnittstelle für das Schreiben und Lesen von Objekten in
die Datenbank realisieren.
1. Wie bekomme ich sowas einheitlich gelöst?
Ist dass eine Fingerübung von dir?
Oder wozu brauchtst du es?

Für praktische Anwendungen nimm ein vorhandenes Framework
wie Hibernate.
Thomas Chojecki
2008-12-17 15:05:36 UTC
Permalink
Post by Thomas Thiele
Post by Thomas Chojecki
ich will eine Schnittstelle für das Schreiben und Lesen von Objekten in
die Datenbank realisieren.
1. Wie bekomme ich sowas einheitlich gelöst?
Ist dass eine Fingerübung von dir?
Oder wozu brauchtst du es?
Für praktische Anwendungen nimm ein vorhandenes Framework
wie Hibernate.
Ja ist eine Übung. Habe es im folgendem Beitrag näher erläutert :)
http://groups.google.com/groups?selm=gib05o%24kac%241%40news.albasani.net
m***@heinerkuecker.de
2008-12-17 10:58:10 UTC
Permalink
Thomas Chojecki schrieb
Post by Thomas Chojecki
ich will eine Schnittstelle für das Schreiben und Lesen von Objekten in
die Datenbank realisieren.
Für eine relationale Datenbank ist dieses Beispiel ok und funktioniert
super. Ich habe aber noch DB4O und dort passt dann die Methode
verbinde(String host ...) nicht mehr.
Ein viel grösseres Problem wird die Suche mit bestimmten
Kriterien sein.

In SQL wird eine WHERE-Klausel verwendet.

In db4o gibt es

Query By Example (QBE)
SODA / Criteria Queries
Native Queries

Irgenwie läuft es darauf hinaus, das eine Expression (Klausel)
je nach Backend-System umgewandelt werden muss.


Ein weiteres Problem ist die Behandlung von
Objekt-Graphen.

In db4o beschreiben sich die Objekte quasi selbst,
SQL ist doof und weiss nichts über Objektverbindungen
ausser bei den Constraints.

Also ist irgendeine Modellbesachreibung,
zum Beispiel in XML, notwendig.

Dann musst Du Änderungen beobachten, um zu wissen,
welche Objekte in der Datenbank angelegt oder überschrieben
werden müssen.

Für eine gute Performance benötigst Du die
Angabe einer Lade-Strategie (lazy, eager)
und einer Lade-Tiefe.

Da hast Du richtig Arbeit.
Post by Thomas Chojecki
Schonmal vielen Dank
Thomas Chojecki
Grüsse
Heiner
Thomas Chojecki
2008-12-17 15:26:08 UTC
Permalink
Post by m***@heinerkuecker.de
Thomas Chojecki schrieb
Post by Thomas Chojecki
ich will eine Schnittstelle für das Schreiben und Lesen von Objekten in
die Datenbank realisieren.
Für eine relationale Datenbank ist dieses Beispiel ok und funktioniert
super. Ich habe aber noch DB4O und dort passt dann die Methode
verbinde(String host ...) nicht mehr.
Ein viel grösseres Problem wird die Suche mit bestimmten
Kriterien sein.
In SQL wird eine WHERE-Klausel verwendet.
In db4o gibt es
Query By Example (QBE)
SODA / Criteria Queries
Native Queries
Bei den relationalen DBs wird das suchen über Stored Procedures gelöst
und wird von der jeweiligen Person dann implementiert. Habe mir da aber
noch nicht soviele Gedanken gemacht. Bei DB4O wird es SODA sein bzw. zum
größten Teil QBE und wenn ich mich jetzt hier nicht vertan habe, könnte
ich das auch via QBE in das Modell übernehmen. Das heißt die Abfrage
wird dann aus dem Example zusammengebaut und an die Datenbank geschickt.
Post by m***@heinerkuecker.de
Ein weiteres Problem ist die Behandlung von
Objekt-Graphen.
In db4o beschreiben sich die Objekte quasi selbst,
SQL ist doof und weiss nichts über Objektverbindungen
ausser bei den Constraints.
Die Verbindungen über FKs / Constraints sind schon realisiert.
Post by m***@heinerkuecker.de
Also ist irgendeine Modellbesachreibung,
zum Beispiel in XML, notwendig.
Da mir das Modell bekannt ist, werde ich es für meinen DB4O Teil
hoffentlich Problemlos realisieren können.
Post by m***@heinerkuecker.de
Dann musst Du Änderungen beobachten, um zu wissen,
welche Objekte in der Datenbank angelegt oder überschrieben
werden müssen.
Für eine gute Performance benötigst Du die
Angabe einer Lade-Strategie (lazy, eager)
und einer Lade-Tiefe.
Das kritischste was passieren könnte ist, dass eine Leitung aus sehr
vielen Teilstücken besteht und diese halt geladen werden müssen.
Post by m***@heinerkuecker.de
Da hast Du richtig Arbeit.
Bin recht optimistisch, wenn die Idee realisiert ist, geht das umsetzten
schnell. Die Komplexität ist auch nicht so hoch und kann ja jederzeit
von uns bestimmt werden. Mich bewegt es einfach nur bisschen mehr Zeit
zu investieren um mal aus Fehlern zu lernen. Ich möchte nicht in der
Praxis in einem Projekt sein und dann mitten drin feststellen, dass das
Modell später nicht Wartbar ist und im schlimmsten Fall nicht realisiert
werden kann.
Post by m***@heinerkuecker.de
Post by Thomas Chojecki
Schonmal vielen Dank
Thomas Chojecki
Grüsse
Heiner
Danke und schöne Grüße
Thomas
Jochen Theodorou
2008-12-17 19:24:10 UTC
Permalink
Also ich geb mal auch meinen Senf dazu
Post by Thomas Chojecki
Hallo NG,
ich will eine Schnittstelle für das Schreiben und Lesen von Objekten in
die Datenbank realisieren.
Ein abstraktes Basismodel habe ich schon fertig, was für jede Datenbank
geerbt wird und dann halt die nötigen Methoden von dem zuständigen
Entwickler ausgeschrieben werden.
public abstract class DBManager {
public abstract void verbinde(String host, int port, String db,...);
public abstract void trenne();
public abstract boolean istVerbunden();http://www.hibernate.org/412.html
public abstract void schreibeObjekt1(Objekt1 o1);
public abstract void schreibeObjekt2(Objekt1 o2);
public abstract Objekt1 leseObjekt1(Objekt1 o1_example);
public abstract Objekt2 leseObjekt2(Objekt2 o2_example);
public boolean pruefeObjekt1(Objekt1 o1) {...}
...
}
das würde ich jetzt ganz anders machen, aber ich bin db4o vorgeschädigt
;) Prinzipiell kommt es darauf an ob du es generisch lösen willst oder
schnell. Wobei die generische Lösung so langsam auch wieder nicht sein muss.

Ich würde wie Stefan auch das Verbinden in den Constructor packen, also
gar nicht Teil der Schnittstelle machen. Dann braucht man eigentlich
kein schreibeObject1 ... schreibeObjektn, sondern eigentlich reicht doch
ein write(Object). Selbiges gilt für read(Object), wobei Object dann für
Query-by-Example genützt werden würde.

Den Prüfteil würde ich garnicht erst zu einem Teil der
Datenbankschnittstelle machen, jedenfalls nciht als Methode. Heute
benutzt man meist Annotationen für sowas, ich würde diese also benutzen.
Oder man macht es noch moderner und macht programming-by-convention, so
wie es bei Grails und Rails üblich ist. Die Idee dahinter ist den
Programmierer der Klassen unverbindlich entscheiden zu lassen ob er
etwas validieren will und wie er es validieren will. Ausserdem hält man
dadurch die Datenbankschnittstelle stabil.

Validierungsannotationen finden sich zum Beispiel hier:
http://www.hibernate.org/412.html

Der Code reduziert sich damit zu:

public abstract class DBManager {
public void write(Object o) {
validate(o);
doWrite();
}
protected abstract void doWrite(Object o);
public abstract Object read(Object o);
public void disconnect();
public void validate(Object o) {...}
}

wobei validate mittels Hibernate Validator implementiert werden könnte.
In validate würde ich nicht mit booleans arbeiten, denn nichts ist
schlimmer als zu wissen das etwas nicht geht, aber nicht zu wissen was
genau es denn ist. Also Exceptions. auf
http://darioquintana.com.ar/blogging/?p=37 findest du ein Beispiel für
die Verwendenung des validators in db4o in einem leicht anderem Kontext.

Für programming-by-convention würde ich Grails als Vorbild nehmen, wie
in zum Beispiel
http://www.communardo.de/techblog/2008/12/04/grails-validierung-nach-mass/

Da ihr aber nicht Groovy macht, sondern wohl eher Java würde ich
vorschlagen etwas ähnliches zu machen. Also eine statische Methode
festen Namens, die ein Objekt der momentanen Klasse als Parameter
bekommt und dieses Objek prüft. Die Implementierung von validate würde
sich dann auf das Aufrufen dieser Methode beschränken, sofern sie
vorhanden ist... mit ein bischen Reflection gar kein Problem.

Gruss theo
Thomas Chojecki
2008-12-17 22:03:18 UTC
Permalink
Post by Jochen Theodorou
Also ich geb mal auch meinen Senf dazu
[...]
Post by Jochen Theodorou
das würde ich jetzt ganz anders machen, aber ich bin db4o vorgeschädigt
;) Prinzipiell kommt es darauf an ob du es generisch lösen willst oder
schnell. Wobei die generische Lösung so langsam auch wieder nicht sein muss.
Das höre ich gerne, neue Lösungsvorschläge zu bekommen.
Post by Jochen Theodorou
Ich würde wie Stefan auch das Verbinden in den Constructor packen, also
gar nicht Teil der Schnittstelle machen. Dann braucht man eigentlich
kein schreibeObject1 ... schreibeObjektn, sondern eigentlich reicht doch
ein write(Object). Selbiges gilt für read(Object), wobei Object dann für
Query-by-Example genützt werden würde.
read(Object) klingt gut, aber wie schon in einem vorherigen Post
geschrieben, wird glaub ich das alleinige Example nicht bei allen Sachen
ausreichen. Müsste aber ne Nacht drüber schlafen um mir genauer Gedanken
zu machen.
Post by Jochen Theodorou
Den Prüfteil würde ich garnicht erst zu einem Teil der
Datenbankschnittstelle machen, jedenfalls nciht als Methode. Heute
benutzt man meist Annotationen für sowas, ich würde diese also benutzen.
Oder man macht es noch moderner und macht programming-by-convention, so
wie es bei Grails und Rails üblich ist. Die Idee dahinter ist den
Programmierer der Klassen unverbindlich entscheiden zu lassen ob er
etwas validieren will und wie er es validieren will. Ausserdem hält man
dadurch die Datenbankschnittstelle stabil.
http://www.hibernate.org/412.html
Höre ich alles zum Ersten mal, werde es mir also erstmal verinnerlichen.
Post by Jochen Theodorou
public abstract class DBManager {
public void write(Object o) {
validate(o);
doWrite();
}
protected abstract void doWrite(Object o);
public abstract Object read(Object o);
public void disconnect();
public void validate(Object o) {...}
}
wobei validate mittels Hibernate Validator implementiert werden könnte.
In validate würde ich nicht mit booleans arbeiten, denn nichts ist
schlimmer als zu wissen das etwas nicht geht, aber nicht zu wissen was
genau es denn ist. Also Exceptions. auf
http://darioquintana.com.ar/blogging/?p=37 findest du ein Beispiel für
die Verwendenung des validators in db4o in einem leicht anderem Kontext.
Das Framework habe ich gerade überflogen, sieht interessant aus.
Post by Jochen Theodorou
Für programming-by-convention würde ich Grails als Vorbild nehmen, wie
in zum Beispiel
http://www.communardo.de/techblog/2008/12/04/grails-validierung-nach-mass/
Da ihr aber nicht Groovy macht, sondern wohl eher Java würde ich
vorschlagen etwas ähnliches zu machen. Also eine statische Methode
festen Namens, die ein Objekt der momentanen Klasse als Parameter
bekommt und dieses Objek prüft. Die Implementierung von validate würde
sich dann auf das Aufrufen dieser Methode beschränken, sofern sie
vorhanden ist... mit ein bischen Reflection gar kein Problem.
Gruss theo
Bevor ich den Beitrag hier durchkaue, vergeht noch ne Weile :)
Aber besten Dank für die Anregung was Validierung betrift.

Gruß
Thomas
Jochen Theodorou
2008-12-17 22:37:05 UTC
Permalink
Thomas Chojecki schrieb:
[...]
Post by Thomas Chojecki
Post by Jochen Theodorou
Ich würde wie Stefan auch das Verbinden in den Constructor packen, also
gar nicht Teil der Schnittstelle machen. Dann braucht man eigentlich
kein schreibeObject1 ... schreibeObjektn, sondern eigentlich reicht doch
ein write(Object). Selbiges gilt für read(Object), wobei Object dann für
Query-by-Example genützt werden würde.
read(Object) klingt gut, aber wie schon in einem vorherigen Post
geschrieben, wird glaub ich das alleinige Example nicht bei allen Sachen
ausreichen. Müsste aber ne Nacht drüber schlafen um mir genauer Gedanken
zu machen.
Query-by-Example reicht dann nicht wenn man sowas hat: gib mir alle
Politiker des Bundestages mit Nebeneinkünften über ihrem Bundestagsgehalt

in anderen Worten: man kann keine Relationen wie <,>,!= ausdrücken.

Allerdings hast du da auch ein großes Problem... denn sowas bedarf einer
Querylanguage oder zumindest einer Art stored Procedure... Allerdings...
wie passt das in eine Schnittstelle mit nur einem read oder leseObjekt1?
Dann müsste man noch sowas wie S.O.D.A nehmen und eine Methode query zur
Datenbank hinzufügen.. oder read dafür benutzen. Allerdings muss dann
jemand auch SODA für relationale Datenbanken schreiben.

Allerdings hat auch SODA einen Nachteil. Will ich sowas machen: "Kürze
die Gehälter des Vorstandes um 50%", und es nur auf der Datenbank
ausführen, dann reicht SODA nicht aus, da es keine updates kennt. Die
soll man nämlich per hand ausführen dann....

[...]
Post by Thomas Chojecki
Post by Jochen Theodorou
Für programming-by-convention würde ich Grails als Vorbild nehmen, wie
in zum Beispiel
http://www.communardo.de/techblog/2008/12/04/grails-validierung-nach-mass/
Da ihr aber nicht Groovy macht, sondern wohl eher Java würde ich
vorschlagen etwas ähnliches zu machen. Also eine statische Methode
festen Namens, die ein Objekt der momentanen Klasse als Parameter
bekommt und dieses Objek prüft. Die Implementierung von validate würde
sich dann auf das Aufrufen dieser Methode beschränken, sofern sie
vorhanden ist... mit ein bischen Reflection gar kein Problem.
Bevor ich den Beitrag hier durchkaue, vergeht noch ne Weile :)
Aber besten Dank für die Anregung was Validierung betrift.
sicher, kein Problem ;)

Gruss theo
Bernd Hohmann
2008-12-17 23:01:39 UTC
Permalink
Post by Jochen Theodorou
Allerdings hat auch SODA einen Nachteil. Will ich sowas machen: "Kürze
die Gehälter des Vorstandes um 50%", und es nur auf der Datenbank
ausführen, dann reicht SODA nicht aus, da es keine updates kennt. Die
soll man nämlich per hand ausführen dann....
Jaja... SODA war so eine Idee von unserem geschätzten Kollegen Carl
Rosenberger, der sich nun hoffentlich endlich sein Entwickler-Schloss in
der Bretagne leisten kann - ich gönne es ihm vom ganzen Herzen.

2002 hatte ich auch einen sehr ähnlichen Ansatz wie SODA, das Projekt
durchgezogen, dabei soviel Geld verbraten um ein Schloss in der Bretagne
zu kaufen und die Idee letztendlich für Scheisse befunden.

Was ein Glück, dass ich diesen Ansatz nie veröffentlicht habe - nun muss
es Carl ertragen ;-)

Bernd
--
Well, there's egg and bacon; egg sausage and bacon; egg and
***@spamonly.de ; egg bacon and spam; egg bacon sausage
and ***@spamonly.net ; spam bacon sausage and spam;spam
egg spam spam bacon and ***@nixwill.de ; spam sausage
Jochen Theodorou
2008-12-18 00:31:11 UTC
Permalink
Post by Bernd Hohmann
Post by Jochen Theodorou
Allerdings hat auch SODA einen Nachteil. Will ich sowas machen: "Kürze
die Gehälter des Vorstandes um 50%", und es nur auf der Datenbank
ausführen, dann reicht SODA nicht aus, da es keine updates kennt. Die
soll man nämlich per hand ausführen dann....
Jaja... SODA war so eine Idee von unserem geschätzten Kollegen Carl
Rosenberger, der sich nun hoffentlich endlich sein Entwickler-Schloss in
der Bretagne leisten kann - ich gönne es ihm vom ganzen Herzen.
hehe, ich auch.
Post by Bernd Hohmann
2002 hatte ich auch einen sehr ähnlichen Ansatz wie SODA, das Projekt
durchgezogen, dabei soviel Geld verbraten um ein Schloss in der Bretagne
zu kaufen und die Idee letztendlich für Scheisse befunden.
*g*
Post by Bernd Hohmann
Was ein Glück, dass ich diesen Ansatz nie veröffentlicht habe - nun muss
es Carl ertragen ;-)
Also schlecht finde ich SODA nicht, es wirkt halt unvollständig.
Allerdings bewege ich mich jetzt eher in der dynamischen Welt und da
gibt es andere Mittel und Wege. Zum Beispiel Groovy Closures, die zur
Laufzeit anhand des Quellcodes in die Datenbankabfragesprache übersetzt
werden. Da muss man dann im Prnzip noch nich einmal eine eigene
Abfragesprache lernen. Der Ansatz hat natürlich auch so seine Problem,
aber die wollen wir in Zukunft auch noch angehen. Die Priorität ist halt
recht niedrig zur Zeit.

db4o bietet ja etwas ähnliches. Und zwar aus Javacode eine Abfrage für
die Datenbank zu erzeugen. Und das hat auch ein ähnliches Problem wie
die Groovy-Variante, allerdings nicht ganz so groß. Und zwar muss der
bytecode verfügbar sein. In einer geschützten Umgebung oder mit zur
Laufzeit erzeugten Klassen wird das nix. Bei der Groovyversion müsste es
der Sourcecode sein leider. Allerdings wollen wir den Source ein Stück
weit verfügbar machen. Jedenfalls genug, damit ein Programm daraus
queries erstellen kann. Weil das aber auch informationen über den
Sourcecode hergibt, die man vielleicht so nicht hergeben möchte sind wir
noch am Diskutieren.

Gruss theo

Jochen Theodorou
2008-12-17 22:43:01 UTC
Permalink
Thomas Chojecki schrieb:
[...]

achja noch eine Anregung falls du Projekte suchst. Grails ha GORM, das
hat eine gewisse Ähnlichkeit zu SODA, allerdings basiert es vollständig
auf dynamischen Methodennamen. GORM ist derzeit relativ fest in Grails
integriert, was bedeutet das es Spring und hibernate benutzt... es wäre
nett eine Version zu haben, die statt dessen db4o benutzt, aber trotzdem
GORM unterstützt.

Gruss theo
Thomas Chojecki
2008-12-17 22:53:06 UTC
Permalink
Post by Jochen Theodorou
[...]
achja noch eine Anregung falls du Projekte suchst. Grails ha GORM, das
hat eine gewisse Ähnlichkeit zu SODA, allerdings basiert es vollständig
auf dynamischen Methodennamen. GORM ist derzeit relativ fest in Grails
integriert, was bedeutet das es Spring und hibernate benutzt... es wäre
nett eine Version zu haben, die statt dessen db4o benutzt, aber trotzdem
GORM unterstützt.
Gruss theo
Ich habe ja noch ein Leben außerhalb von Java und des Studiums. ;)
Gruß zurück
Thomas
Loading...