Best Practices für Data Binding ohne Hilfstools

Status
Nicht offen für weitere Antworten.

Marco13

Top Contributor
Hallo

Wenn man komplexe Objekte von Java in XML speichern will, gibt es dafür etliche Tools. Wenn man nun aber KEINE Tools verwenden will, sondern die Daten von Hand speichern will, wie macht man das am besten? Man kann es "irgendwie" machen, aber wenn es um XML-Strukturen mit Veschachtelungstiefen von 10 (oder so) geht, kann man da wohl schon einiges falsch machen.

Ganz grob (!) und sinngemäß skizziert(!) könnte man verschiedene Ansätze verfolgen:

1. Man hat eine Klasse, die die XML-Verarbeitung regelt. Sie parst den kompletten XML-Baum, läuft im XML-Baum "runter", baut an den Blättern die "primitiven" Objekte, um diese dann zu immer größeren, komplexeren Objekten zusammengebaut werden, bis am Ende das riesige, komplexe Objekt erstellt werden kann, das der XML-Datei entspricht. Zum Schreiben von XML läuft das ganze analog.

2. Für jede Klasse gibt es einen passenden XMLReader/Writer, der einen Knoten bekommt, und daraus das passende Objekt erstellt (oder umgekehrt). Jeder dieser XMLReader verwendet für die unter-Objekte kleinere XMLReader als "Building Blocks".

3. Jede Klasse hat (sinngemäß) einen no-args-Konstruktor, und zwei Methoden wie "readFromNode(Node n)" und "Node createNode()", die die XML-Verwaltung für die Klasse selbst regeln.

Für mich kommen eigentlich nur zwei davon in Frage, aber welche davon sich (bei denjenigen, die sich damit schon intensiver beschäftigt haben) "bewährt" haben, würde mich interessieren. (Ich zähle aber mal nicht meine subjektiven Pros/Cons auf, um die Antworten nicht zu sehr zu beeinflussen :))

bye
 

Ullenboom

Bekanntes Mitglied
Hier finde ich das Collecting Parameter Pattern zur Reduzierung von temporären Objekten gut angebracht -- alle Knoten, die eine XML-Repräsentation liefern, schreiben diese in einen übergebene Behälter. Hierfür finde ich die Java 5 Schnittstelle java.lang.Appendable wie geschaffen:
Code:
class Customer
{
 ...
 void toXml( Appendable a ) {
  a.append( XML-Repräsentation erzeugen );
 }

Der Methode toXml() kann man nun so was wie StringBuilder, aber auch alle Writer rekursiv übergeben.

Beste Grüße

Christian
 

AlArenal

Top Contributor
Nun kann man vorzüglich diskutieren, ob es Aufgabe einer Datenklasse ist, die eigene De-/Serialsierung zu erledigen. Man baut ja auch keine Häuser mit eingebauter Abrissbirne....
 

Marco13

Top Contributor
@Ullenboom: Das wäre also im Prinzip die dritte Variante - allerdings stört mich daran genau das, was AlArenal auch angedeutet hat: Ich finde es eigentlich nicht schön, wenn eine Klasse solche Meschanismen selbst kennt (weil sie nichts mit dem abstraken Modell zu tun haben, für das die Klasse steht). Wo jetzt die Grenze verläuft, weiß ich auch nicht so genau (man könnte ja so dreist sein, die toString() Methode so zuüberschreiben, dass sie XML zurückgibt :shock: - von wegen: "Das gehört nicht in die Klasse" :wink: ). Insgesamt tendiere ich eigentlich eher zur zweiten Variante - aber DA stört mich, dass man u.U. Dinge NUR public machen muss, um sie zu XMLen/unXMLen, obwohl diese Sachen ansonsten garnicht public sein müßten... Hm... ???:L
 

SnooP

Top Contributor
nein... - da gibts natürlich auch versch. Dinge... entweder man guckt per Reflection nach den get-Methoden in der Klasse und versteht sie als Bean... dann muss man halt dafür sorge tragen, dass alle zu persistierende Felder entsprechende get/set-Methoden bereitstellen oder...
Man kopiert ebenfalls per Reflection tatsächlich die Felder, die mit entsprechender Sicherheitseinstellung dann auch auf private/final-Felder zugreifen kann... - XStream geht z.B. auch so vor...
Damit bräuchtest du auch nicht für jede Klasse noch xml-reader/writer... das wäre mir persönlich zu umständlich, weil du bei der Erweiterung deiner Klassen dann auch da immer noch drauf achten musst.. - also eher schlecht.
 

Ullenboom

Bekanntes Mitglied
Den eigenen Klassen so was wie toXml()/fromXml() zu geben ist sicherlich das einfachste und "irgendwie" auch objektorientiert. Das Objekt "kann" was, nämlich eine XML-Repräsentation zu geben. Daher finde ich das so erst mal OK. Natürlich gibt es ein Hammer-Argument, was du schon genannt hast, was dagegen spricht: XML-Erzeuger-Code gehört nicht in eine normale Geschäftsklasse, weil das nicht ihrer Verantwortung ist. Wo also dahin? Hier kommt so etwas wie das Memento-Pattern ins Spiel, also die externe Abbildung auf eine andere Klasse zu verschieben. Da hast du schon die XML-Abbildungs-Klassen genannt. Aber eine Klasse pro Knoten finde ich da sehr aufwändig. Das zu automatisieren wären hübsch und Techniken wie Reflection hat SnooP schon genannt. Eine simple Idee zum Selbermachen wäre folgende:

class XmlEncoder
{
String toXml( Class nodeClass )
{
if ( nodeClass.equals(Customer.class) )
return XML-Serialisierung vom Customer.
}
}

Ist der XmlEncoder im gleichen Paket, so reichen dann paketsichtbare Eigenschaften bei den Geschäftsklassen. Wobei hier auch SnooP recht hat: Getter sind nicht verkehrt.

Vielleicht möchtest du dich doch mit JAXB oder XStream anfreunden :) Ich arbeite gerne mit beiden (seit Java 6 aber mehr mit JAXB 2.)

Grüße

Christian
 

kleiner_held

Top Contributor
Ich habe auch schon mehrmals die 3te Variante verwendet, da sie erst mal sehr einfach und auch übersichtlich ist. Wenigstens so lange, wie der Umfang der entsprechenden Methoden noch in einem überschaubaren Rahmen bleibt. Gerade wenn man sowieso schon eine baumartige Modellstruktur mit einem Root-Objekt hat, läßt sich das ganz gut umsetzen. Auch wenn dieses Design zugegebenermaßen nicht perfekt ist.

Von Reflection halte ich allerdings in dem Zusammenhang gar nichts, da man dann einfach keine stabile Schnittstelle hinbekommt. Gerade wenn man den Mechanismus für eine Speicherfunktion nutzt, sollte man versuchen das XML Format über verschiedene Programmversionen konsistent zu halten. Ist das durch größere Änderungen nicht mehr möglich, kann man immer noch eine neue Version seiner Schnittstelle verfassen, aber man hat wenigstens volle Kontrolle darüber wann sich die XML-Struktur ändert. Bei Verwendung von Reflection läuft man andauernd Gefahr, das sich durch kleinere Änderungen im Modell plötzlich unbeabsichtigt die Schnittstelle geändert hat, nur weil man eine neue protected Membervariable oder ein Bean-Property hinzugefügt hat.
 

Marco13

Top Contributor
@Ullenboom: Der XMLEncode sieht jetzt aber eher wie die erste Variante aus ???:L (das war aber die, die für mich nicht in Frage käme - zu viel "Macht" in einer Klasse, sehr unübersichtlich).

Reflection fällt schonmal in allen Fällen weg (das gilt auch für Tools, die intern Reflection verwenden) : Das ganze wird am Ende obfuscated, und damit ist Reflection leider nichtmehr anwendbar.

Vermutlich wird es auf eine Mischung der letzten beiden rauslaufen. Eigentlich hätte ich gerne ein einheitliches, konsistentes Konzept für alles, aber offenbar gibt's die eierlegene Wollmilchsau in diesem Sinne nicht. Vermutlich werden "komplexe" Klassen ihre eigenen toXML/fromXML-Methoden anbieten, mehrere kleine Klassen (die sinngemäß zusammengehören oder ähnlich sind) können mit einem XMLEncode/Decoder abgehandlet werden (um nicht 1000e neue Klassen erzeugen zu müssen) und die elementarsten Sachen (Strings, ints, Arrays) werden (wie jetzt schon) von einer XML-Utility-Klasse behandlet. Man kann die einzelnen XMLEncoder/Decoder-Klassen bzw. die fromXML/toXML-Methoden ja so bauen, dass man relativ leicht zwischen beiden Welten wechseln kann.

Erstmal danke für alle bisherigen Tipps und Anregungen. Weitere Kommentare sind aber immer erwüscht :D
 

SnooP

Top Contributor
wollt ihr wirklich eure public-Methoden obfuscaten? Ich kenn das, dass man die halt offen lässt... dadurch könnte man dann wunderbar per Reflection auf die getter und setter einer Klasse zugreifen und das Speichern/Populaten darüber erledigen...
 

Marco13

Top Contributor
Es wird ALLES obfuscated, außer den Klassen/Methoden, die für das Ansprechen des Porgrammes von außen benötigt werden (und das sind nur ganze wenige, im Vergleich zur Menge ALLER public Klassen/Methoden).
 

AlArenal

Top Contributor
Buäh, da halte ich ja wenig bis gar nichts von. Da ist doch dann alles, was an Stacktraces und Logging-Infos geworfen wird für die Tonne, oder nicht?
 

Marco13

Top Contributor
Wenn ein Kunde einen Stacktrace zu Gesicht bekommt, ist eh irgendwas im Argen - egal, ob obfuscated oder nicht :wink: Irgendwie muss das ganze ja gegen reverse engineering geschützt werden (und dass das "Geheimnisprinzip" nicht eigehalten wurde, bemängele ich selbst schon die ganze Zeit, aber ... du weißt da vielleicht, wie das ist... :roll: )
 

SnooP

Top Contributor
nunja... ich würde als Kunde ehrlich gesagt überhaupt nix kaufen, wo ich nicht auch den sourcecode zu bekomme ;) - wenn die Firma weg ist, ist dann auch für alle Zeiten mein System in Stein gemeißelt...

der Stacktrace ist ja trotzdem für's logging interessant... sprich man muss dem Kunden ja den Fehler nicht direkt vor augen führen - mail an support, ablegen in die db oder in nen log-file reicht ja schonn und man hat erheblich mehr Informationen als die Meldung vom Kunden "das geht irgendwie nicht!".
 

AlArenal

Top Contributor
Schutz vor Reverse Engineering gibts bei uns nicht. Das war eine ganz bewusste Entscheidung von mir. Wenn ein Kunde für mehrere Teuros ne Software, für viele weitere Teuros Schulung und für noch mehr Teuros Anpassungen bekommt, dann tue ich es mir nicht an auf mein liebgewonnenes Logging zu verzichten und dumm dazustehen, wnn es irgendwo hakt, weil ich schwer bis gar nicht nachvollziehen kann was los ist. Da müsste ich schon sehr paranoid sein...

Das ist auch eine Sache von gegenseitigem Vertrauen. Ich bin doch nicht bei Microsoft :p

Wenn es dann klemmt lassen wir uns, wie SnooP bereits anmerkte, die Logs zuschicken. Die Clients (Java) und mein Teil der Serveranbindung (PHP) haben ihre Logfiles, die vom jeweiligen User / Admin leicht an uns versandt werden können und mir neben den Fehlerbeschreibungen des Kunden in unserem Bug Tracking System wertvolle Zusatzinfos geben, ohne die ich wie schon gesagt meist einfach nur mit der Achsel zucken könnte.

Was sagt der Kunde wohl, wenn ich ihm sage, dass ich den Fehler nicht reproduzieren und daher auch nicht abstellen kann? Doof, oder?
 

Marco13

Top Contributor
Ich finde das auch ... suboptimal ... wir verkaufen das Produkt zwar nicht direkt an den Endkunden, aber natürlich wird das Probleme geben, wenn DOCH mal ein Stacktrace auftaucht, und darin dann Zeilen wie
c.a.f.s.for (Unknown Source)
c.a.f.t.while (Unknown Source)
vorkommen ... Derenige, der diese Entscheidung getroffen hat, war mit an Sicherheit grenzender Wahrscheinlichkeit kein Programmierer, sondern jemand "wichtiges". (Ihr wißt schon - diese Leute im Pinguin-Kostüm). Naja. Das hat mit dem DataBinding und XML jetzt aber schon nichtmehr so viel zu tun.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
S Jackson: Erstellen Sie Klassen für Jackson aus XSD XML & JSON 2
N JAXB: Überflüssiges Wrapper-Tag für Map-Einträge XML & JSON 0
H Editor für Apache FOP XML & JSON 5
E Gibt es denn einen XML-Parser für JUnit-Tests? XML & JSON 6
A XMLRPC für Java XML & JSON 3
S Ersatz für die veraltete Klasse XPath XML & JSON 1
D ods./Excel Tabelle oder doch SQL für nen Anfänger? XML & JSON 5
S Xml File für den Aufbau einer anderen Xml Datei XML & JSON 6
R Rückgabewert für XML-Abschnitt XML & JSON 2
X JDom für SOAP Dateien geeignet? XML & JSON 3
D eine Schema für ein andere Schema XML XML & JSON 14
T XML-Stream als Quelle für FOP XML & JSON 4
Z Tutorial für JDOM (XSD-Shema) XML & JSON 3
D [EMF,XSD] PatternMatcher für eigene Methoden benutzen XML & JSON 3
F Standard für das erstellen von XML? XML & JSON 4
H XML plattformunabhängig/Open Source für Java XML & JSON 4
G Idee für kleines Vorführprojekt XML & JSON 5
isowiz Welches Persistenzframework für XML? XML & JSON 3
T Java Klasse für gegebenes XML erstellen XML & JSON 4
B XML file für schtasks XML & JSON 5
G XPath gesucht für Tag mit konkretem Content XML & JSON 2
F beste lib für xml serialisierung - deserialisierung XML & JSON 4
HeRaider Steuerzeichen für Zeilenumbrüche XML & JSON 2
T Editor für XML-Dialekt entwickeln XML & JSON 3
M brauche große XML-Datei für XPath-Tests XML & JSON 4
A XML für Einstellungen - welche Strategie verwenden? XML & JSON 4
M XSL-File für Transformation verwenden XML & JSON 3
C Pfadangabe für Bilder XML & JSON 2
J Client für WebService programmieren (aus WSDL-File) XML & JSON 15
T DTD für XML-Instanz einbinden? XML & JSON 4
Z beispiel für valides Xml-Dokument durch XML-Schema XML & JSON 5
G XML als "Datenbank" für kleine Daten XML & JSON 2
D Suche eine OnlineQuelle für SAX XML & JSON 2

Ähnliche Java Themen

Neue Themen


Oben