Universität zu Lübeck Institut für Informationssysteme Die Persistenzschicht Interfaces, Muster...
Transcript of Universität zu Lübeck Institut für Informationssysteme Die Persistenzschicht Interfaces, Muster...
Universität zu LübeckInstitut für Informationssysteme
Die Persistenzschicht
Interfaces, Muster und DOM
Persistenzschicht
• Speicherung und Laden von fachlichen Objekten
• Mapping zwischen Objekten und „XML“
• kein Wissen über die Anwendungsschicht, Präsentationsschicht
Design der Persistenzschicht
• Zugriff von aussen nur über eine Klasse -> Fassade
• Fassade wird zunächst als Interface modelliert
• Implementierung als Singleton d.h. nur ein Examplar der Klasse kann erzeugt werden
• XML-Objekte werden als DOMs persistent abgelegt (hier: mittels Infonyte)
Entwurfsmuster - Singleton
• Ziel: von einer Klasse existiert nur ein einziges Objekt -> zentraler Zugriffspunkt
• Beschreibung: private-Konstruktor verhindert unkontrolliertes erzeugen von Objekte mittels new
• mittels statischer Methode erhält man Referenz auf einziges Objekt.
Implementierung des Singleton
public class Singleton{private static Singleton instance = null;private int datum;
private Singleton(){}public static Singleton getInstance(){
if(instance == null)instance = new Singleton();
return instance;}public void setDatum(int d){this.datum = d;}public int getDatum(){ return datum;}
}
Entwurfsmuster Fassade
• Ziel: soll Abhängigkeiten zwischen Klassen reduzieren -> Subsystem wird durch einheitliche Schnittstelle gekapselt.
Fassade
Klient KlientKlient
Klient
KlientKlient
Subsystem Subsystem
Interface IPersistentMarktplatz
• commitBestellung(IBestellung bestellung);
• …
• commitPerson(IPerson person);
• IBestellung getBestellung(String bestellungID);
• …
• IMarktteilnehmer getMarktteilnehmer(String marktteilnehmerID);
• String getMarktteilnehmerID();
• Vector getBestellungen();
• removeBestellung(String bestellungsID);
• …
• removeMarktteilnehmer(String marktteilnehmerID);
Speichern von Objekten
• Mapping von Objekten (Person, …,Bestellung) auf XML-Objekte (DOM)
DOM
• generisches Objektmodell für XML-Dokumente
• tree of nodes – enthält und erhält Daten und Struktur eines XML-Dokuments
• dieser tree of nodes kann mittels DOM API modifiziert und bearbeitet werden
• DOM ist Sammlung von Interfaces
• Siehe Infonyte DB API
DOM
• Im DOM ist alles ein Knoten (Node)
• Das gesamte XML-Dokument, egal wie einfach wird in einen tree of nodes umgewandelt
• Der Wurzelknoten eines DOMs ist immer ein document object
DOM
<?xml version=“1.0“?>
<addressbook>
</addressbook>
<person>
</person>
<person>
</person>
<name>Henrike S.</name>
<email>schuhart@ifis….</email>
<name>...</name>
<email>…</email>
document
addressbook
person
person
name=“Henrike S.“
email=“schuhart@..“
name=“…“
email=“…“
Wichtige DOM APIs
<<interface>> Node
int getNodeType();String getNodeValue();NodeList getChildNodes();boolean hasChildNodes();Node removeChild(Node oldChild);
<<interface>> NodeList
int getLength();Node item(int i);
<<interface>> Element
public NodeListgetElementsByTagName(String tag);String getAttribute(String name);Attr getAttributeNode(String name);String getTagName();
<<interface>> Document
Element getDocumentElement();Attr createAttribute(String name);Element createElement(String tagName);…
Das Node InterfaceInterface nodeName nodeValue attributes
Attr name of attribute
value of attribute null
Comment "#comment"
content of the comment
null
Document "#document"
null null
Text “#text“ content of the text node
null
Element tag name null NamedNodeMap
Wichtiges zum DOM
• Element-, Attribut-, Text-Knoten werden immer über den Dokumentknoten erzeugt und erst anschließend als Kind an ihren eigentlichen Elternknoten gehängt
• In <name>Henrike S.</name> wird ein Element „name“ mit einem Textknoten als Kind erzeugt, der Textknoten hat als Wert „Henrike S.“
• Alle Nodes eines Dokuments können nicht einfach in ein anderes übernommen werden ->import erforderlich
DOM Bsp.
• Document document=…• Element person =
document.createElement(“person“);• document.appendChild(element);• Attr id = document.createAttribute(“ID“);• id.setValue(“123“);• element.setAttributeNode(id);• Element name = document.createElement(“name“);• person.appendChild(name);• Text textName =
document.createTextNode(“Henrike“);• name.append(textName);
Mapping von IBestellung ->Element(bestellung) (Bsp.)
• public static Node map(IBestellung bestellung, Document document)• {• Element element = document.createElement("bestellung");• if(bestellung.getBeschreibung()!=null)• createElement("beschreibung",bestellung.getBeschreibung(),document,element);
• Vector positionen = bestellung.getPosition();• for(int i=0; i<positionen.size();i++)• {• Element position = document.createElement("position");• element.appendChild(position);• map((IBestellposition)positionen.get(i),document,position);• }
• element.setAttribute("bestellungsID",bestellung.getBestellungsID());•
element.setAttribute("anbieterID",bestellung.getAnbieter().getMarktteilnehmer().getMarktteilnehmerID());
• element.setAttribute("kaeuferID",bestellung.getKaeufer().getMarktteilnehmer().getMarktteilnehmerID());
• return element;• }
Arbeiten mit PDOMs und Infonyte
• einfache Hilfsklasse: Util.java
• wichtig: liefert PDOMs, pdom.getDocument() liefert das dazugehörige DOM-Objekt
• wichtig: immer Referenz auf PDOM und DOM behalten!!!
• Infonyte APIs und Dokumentation
Laden von Objekten
• Mapping von XML-Objekten (DOMs) auf Java-Objekte der Klassen (Person, …,Bestellung)
Mapping von Element(bestellung) ->Bestellung (Bsp.)
• public static IBestellung toBestellung(Element element)• {• IBestellung bestellung;• String bestellungsID = element.getAttribute("bestellungsID");• String anbieterID = element.getAttribute("anbieterID");• String kaeuferID = element.getAttribute("kaeuferID");• bestellung = new BestellungProxy(bestellungsID,anbieterID,kaeuferID);
• String beschreibung = getContent("beschreibung",element);• if(beschreibung!=null)• bestellung.setBeschreibung(beschreibung);
• NodeList nl = getChilds("position",element);• for(int i=0; i<nl.getLength();i++)• {• Element position = (Element)nl.item(i);• bestellung.addPosition(toBestellposition(position,bestellung));• }• • return bestellung;• }
Laden von Objekten
• Was passiert, wenn ich Anbieter mit Referenzen auf Katalog lade?
• Problem: theoretisch kann durch Laden eines Objekts ganze Datenbank geladen werden
• Lösung: Proxy
Entwurfsmuster Proxy
• Ziel:
Einführung eines Stellvertreterobjekts, um Zugriff auf ein Objekt zu kontrollieren
• Beschreibung:
Klient benutzt Proxy statt Original. Proxy verwaltet Referenz auf Original und leitet Anforderungen vom Klient geeignet weiter.
Entwurfsmuster Proxy
Klient Subject
+request()
Proxy
+request()
RealSubject
+request()
request(){ realSubject.request();}
Entwurfsmuster Proxy (Bsp.)
public class BestellungProxy implements IBestellung{
private Bestellung bestellung; private String anbieterID; private String kaeuferID;
public BestellungProxy(String bestellungsID, String anbieterID, String kaeuferID)
{ this.bestellung = new
Bestellung(bestellungsID,null,null,null); this.anbieterID = anbieterID; this.kaeuferID = kaeuferID; } public IAnbieter getAnbieter() {
IAnbieter anbieter = this.bestellung.getAnbieter(); if(anbieter!=null) return anbieter; anbieter =
PersistentMarktplatz.getInstance().getAnbieter( this.anbieterID);
this.bestellung.setAnbieter(anbieter); return anbieter; }
public class Bestellung implements IBestellung{
String bestellungsID; IAnbieter anbieter; IKaeufer kaeufer; ... public Bestellung(String bestellungsID,
IAnbieter anbieter, IKaeufer kaeufer, IBestellposition bestellposition)
{ this.bestellungsID = bestellungsID; this.anbieter = anbieter; this.kaeufer = kaeufer; this.position = new Vector(); if(bestellposition!=null) this.position.add(bestellposition); } public IAnbieter getAnbieter() { return this.anbieter; }