Inhalt In Java gibt es mehrere Klassenbibliothek-Pakete, die Datenstrukturen und Operationen für die grafische Darstellung von Fenstern und Benutzerinteraktionen erlauben (wie Sie es gewohnt sind) Vorlesung Informatik II Universität Augsburg Sommersemester 2011 In diesem Kapitel werden wir besprechen: Grundlagen des Pakets java.awt Einfach(st)e Anbindung von Fenstern an Datenklassen Prof. Dr. Robert Lorenz Später: Grafische Benutzerschnittstelle und Schichtenarchitektur Paket java.swing Lehrprofessur für Informatik 07. Java: GUI und Ereignisbehandlung – Teil 1 1 Exkurs: GUI-Elemente 2 Exkurs: GUI-Elemente Grundbegriffe Grundbegriffe Dialog Fenster zur Interaktion mit dem Benutzer Dialog Fenster zur Interaktion mit dem Benutzer Primärdialog: zur direkten Aufgabenerfüllung z.B. Editor modaler Dialog muss beendet werden vor Aktivierung eines anderen Fensters z.B. Speichern unter, Mitteilungen Sekundärdialog: für situationsabhängige zusätzliche Informationen wird aus Primärdialog gestartet nach Beendigung wird Primärdialog fortgesetzt z.B. Drucken, Speichern unter, Formeln einfügen, Suchen ... nicht modaler Dialog kann unterbrochen werden z.B. Suchen 3 4 Inhalt Fenster Später: Vorgehen zum systematischen Konstruieren der GUI zu vorgegebenen Datenklassen (Erfassungsfenster, Listenfenster, Dialogführung) Ein leeres Fenster (Klasse Frame) import java.awt.*;//Import aller Klassen des Pakets public class Test { public static void main (String args[]){ Frame F=new Frame(); F.setSize(300,300);//Breite und Höhe in Pixeln F.setVisible(true);//sichtbar machen } } Jetzt: Vereinfachte Anbindung von Fensterklassen an Datenklassen Zugriff auf Daten von Objekten einer Klasse Zugriff auf Beziehungen zwischen Objekten 5 Fenster 6 Fenster Besser: Entkoppelung der Programmklasse + eigene Fensterklasse als Spezialisierung Besser: Entkoppelung der Programmklasse + eigene Fensterklasse als Spezialisierung public class MeinProgrammGUI extends Frame { public MeinProgrammGUI (){ super();//Konstruktoraufruf von Frame (opional) setSize(300,300); setVisible(true); } } public class meinProgramm { public static void main (String args[]){ new MeinProgrammGUI();//Anonymes Objekt erzeugen } } + Frame + MeinProgrammGUI Benutze Konstruktor zur Darstellung des Fensters 7 8 Fenster - Vererbungshierarchie Fenster Object Ausgewählte Klassen und Operationen: Component (Graphische Benutzerschnittstelle) Frame: Fenster mit Titel void setMenuBar(MenuBar b): Menubar b hinzufügen Container (kann andere Komponenten enthalten) MenuBar: Leiste, um Menüs aufzunehmen Menu add(Menu m): Menu hinzufügen Panel (für Fensterkomponenten) Window (Primärfenster ohne Rand) Menu: Menü mit Titel, das verschiedene Menüpunkte enthalten kann MenuItem add(MenuItem i): Menüpunkt hinzufügen Frame (mit Rand und Titel) MenuItem: Menüpunkt mit Titel, um Aktionen auszuführen oder Optionen zu setzen oder andere Menüs aufzunehmen (zum Ausklappen) Dialog (für Dialoge) 9 Fenster 10 Fenster BorderLayout: Ausgewählte Klassen und Operationen: Frame void setLayout(LayoutManager l): Komponenten durch Layout organisieren Component add(...): Komponenten gemäß Layout hinzufügen North West LayoutManager: Schnittstelle zur Festlegung der Darstellung von Komponenten innerhalb eines Containers BorderLayout: siehe nächste Folie FlowLayout: von links nach rechts (horizontal) fließend Gridlayout: wie Gitter/Tabelle Center East South Label: Komponente zur Darstellung von Text 11 12 Fenster Fenster Ausgewählte Klassen und Operationen: Ausgewählte Klassen und Operationen: Panel: Komponente zur Aufnahme weiterer Komponenten nach Layout Voreinstellung: FlowLayout Component add(...): Komponenten gemäß Layout hinzufügen Frame void setLocation(int x, int y): Linke obere Ecke des Frames void setVisible(true): Frame sichtbar machen void pack(): Optimale Größe zur Darstellung aller Komponenten setzen Button: Schaltfläche mit Titel, um Aktionen auszuführen Dialog: Fenster mit Titel zur Darstellung von Dialogen zu einem Frame oder zu einem anderen Dialog modal oder nicht modal Operationen ähnlich wie bei Frame PopupMenu: über Rechtsmausklick erreichbares Menu wird einer Komponente zugeordnet 13 Fenster 14 Fenster Ausgewählte Klassen und Operationen: Ausgewählte Klassen und Operationen: TextField: Zur Eingabe von Text (einzeilig) String getText(): Eingegebenen Text auslesen void setText(String text): Text setzen TextArea: Zur Eingabe von Text (mehrzeilig, mit Scrollbar) ähnlich zu TextField Choice: Ausklappbare Liste von Strings zur Auswahl unter verschiedenen Unterpunkten (Einfach- oder Mehrfachauswahl) void add(String titel): Unterpunkt hinzufügen void select(String titel): Unterpunkt auswählen String getSelectedItem(): Ausgewählten Unterpunkt zurückgeben 15 List: Liste von Strings zur Auswahl unter verschiedenen Unterpunkten (ähnlich zu Choice) void dd(String text): Unterpunkt hinzufügen void remove(String text): Unterpunkt entfernen void removeAll(): alle Unterpunkte entfernenntfernen 16 Fenster Fenster Anwendungsfenster Dialogfenster (vereinfacht, exemplarisch) Sinnvolle Komponenten: Button close: Schließen des Fensters Menu bearbeiten: Öffnen von Dialogen zur Bearbeitung von Daten PopupMenu bearbeitenPm: dasselbe als Popupmenu Anbinden von Dialogfenstern an Datenklassen zur Bearbeitung von Daten: Erstellen von Daten Anzeigen von Daten Modifizieren von Daten Löschen von Daten Komponenten mit Hilfe von Panels organisieren Binde an jede Datenklasse MeineKlasse und ihre Containerklasse ein Dialogfenster MeineKlasseGUI an Layout hinzufügen 17 Fenster 18 Fenster Dialogfenster (vereinfacht, exemplarisch) Dialogfenster (vereinfacht, exemplarisch) + Dialog + MeineKlasseGUI + MeineKlasseGUI() ... + save() + update() + load() + MeineKlasseGUI 0..* 0..1 subject + MeineKlasse 0..* container 1..1 Eingegebene Daten an subject übergeben Liste aller Objekte in container neu anzeigen Objektdaten von subject laden + MeineKlasseContainer 19 20 Fenster Fenster Dialogfenster (vereinfacht, exemplarisch) Dialogfenster (vereinfacht, exemplarisch) Mit passenden grafischen Komponenten zum Eingeben und Anzeigen aller Attributwerte: Benutze Konstruktor zum Initialisieren aller grafischer Komponenten Einwertiges Attribut: TextField Aufzählungs-Attribut: Choice Mehrwertiges Attribut: List Sollten grafische Komponenten Attribute der Fensterklasse sein? Nur diejenigen zur Aufnahme von Attributwerten (Textfelder,...) sonst: lokale Variablen im Konstruktor (Schaltflächen,...) Mit grafischer Komponente zum Anzeigen und Auswählen von erzeugten Objekten: List 21 Fenster 22 Fenster Dialogfenster (vereinfacht, exemplarisch) Dialogfenster (vereinfacht, exemplarisch): Mit Schaltflächen / Menüpunkten zum Ausführen obiger Aktionen und zugehörigen Operationen Attribute: Referenzattribute & Grafische Komponenten zur Aufnahme von Attributwerten public class MeinKlasseGUI extends Dialog { keine üblichen Verwaltungsoperationen für die Attribute und Beziehungen (überflüssig) private MeineKlasse subject;//Referenz Datenobjekt private MeineKlasseContainer container;//Referenz Container private TextField meinAttribut;//Ausgabe Attribut Datenobjekt ... private List alleObjekte;//Ausgabe aller Datenobjekte ... 23 24 Fenster Fenster Dialogfenster (vereinfacht, exemplarisch): Dialogfenster (vereinfacht, exemplarisch): Konstruktor: Fensteraufbau & Initialisierungen Operation save(): Auslesen der Werte aus den grafischen Komponenten und Erzeugen eines neuen Objekts mit diesen Werten public MeinKlasseGUI(Frame f){ super(f,“Objekte verwalten“,false);//Frame-Konstruktor setLayout(new GridLayout(0,1));//eine Spalte,beliebig viele Zeilen Panel p = new Panel(); meinAttribut = new TextField(20); p.add(meinAttribut); Button speichern = new Button(“Speichern"); p.add(speichern); add(p); container = MeineKlasseContainer.instance(); subject = null;//Initialisierung der Referenzen pack(); setVisible(true); } public void save(){ subject = new MeineKlasse(...); subject.setMeinAttribut(meinAttribut.getText()); ... } 25 Fenster 26 Fenster Dialogfenster (vereinfacht, exemplarisch): Dialogfenster (vereinfacht, exemplarisch): Operation update(): Löschen aller dargestellten Listenelemente und neu Laden aus dem Container Operation load(): Laden der Werte eines aus der Liste selektierten Objekts public void update(){ alleObjekte.removeAll(); for(MeineKlasse o:container){ alleObjekte.add(o.toString()); } } if (alleObjekte.getSelectedItem() != null){ Iterator<MeineKlasse> it = container.iterator(); while (it.hasNext()){ MeineKlasse o = it.next(); String auswahl = alleObjekte.getSelectedItem(); if (o.toString().equals(auswahl)){ subject = o;} } ... meinAttribut.setText(subject.getMeinAttribut()); ... 27 28 Ereignisbehandlung Ereignisbehandlung Noch können wir nichts mit dem Fenster anfangen Benutzeraktionen lösen sog. Ereignisse (Events) aus: Es lässt sich nicht schließen Dialogfenster lassen sich nicht öffnen Keine Reaktion auf Drücken von Schaltflächen Klicken auf Schaltfläche: ActionEvent Klicken mit der Maus auf Komponenten: MouseEvent Betätigen von Keyboardtasten: KeyEvent Betätigen von Fensterfunktionen: WindowEvent … Es fehlt noch die sogenannte Ereignisbehandlung Events sind Java-Objekte, die Informationen über Benutzeraktionen kapseln Die Eventklassen bilden eine Vererbungshierarchie (siehe API) 29 Ereignisbehandlung Ereignisbehandlung Objekte, die auf Benutzeraktionen reagieren sollen (z.B. Fenster), müssen diese Ereignisse abhören können AWTEvent ActionEvent AdjustmentEvent ConzainerEvent ComponentEvent InputEvent FocusEvent 30 TextEvent Man kann ereignisempfangende Objekte (Fenster) bei ereignisauslösenden Objekten (Button) als Ereignisabhörer (EventListener) registrieren WindowEvent EventListener ist eine Schnittstelle, die festlegt, mit welchen Operationen auf ein Ereignis regiert werden kann PaintEvent KeyEvent Für jede Ereignisart gibt es eine eigene EventListenerSchnittstelle (ActionListener, MouseListener, …) MouseEvent 31 32 Ereignisbehandlung Ereignisbehandlung Für die Ausführung von Benutzeraktionen zuständige Klassen (ereignisempfangende Klassen) müssen die entsprechende EventListener-Schnittstelle implementieren <<interface>> EventListener <EreignisBehandlungs Operationen> Für die Ausführung von Benutzeraktionen zuständige Klassen (ereignisempfangende Klassen) müssen die entsprechende EventListener-Schnittstelle implementieren <EreignisauslösendeKlasse> addEventListener() removeEventListener() Ereignisauslösende Objekte benachrichtigen alle bei ihr registrierten Ereignisabhörer … ... durch Aufruf der zum Ereignis gehörenden Operation der Ereignisabhörer-Schnittstelle EventObject <EreignisEmpfangendeKlasse> <EreignisBehandlungsOperationen> getSource() ... 33 Ereignisbehandlung Ereignisbehandlung Beispiel: ActionEvent, ActionListener (Buttons) <<interface>> ActionListener actionPerformed() MeinFenster actionPerformed() 34 Beispiel: ActionEvent, ActionListener (Button close) public class meinFenster extends Frame implements ActionListener{ public meinFenster(){ ... Button close = new Button(“close“); add(close); close.addActionListener(this);//Fenster bei Button anmelden ... } public void actionPerformed(ActionEvent e){ if (e.getActionCommand().equals("close")){ dispose();//Fenster schließen System.exit(0);//Anwendungsresourcen freigeben } } } Button addActionListener() removeActionListener() ActionEvent getActionCommand() ... 35 36 Ereignisbehandlung Ereignisbehandlung Beispiel: WindowEvent, WindowListener (Fenster) Beispiel: WindowAdapter (mit leeren Implementierungen) WindowAdapter <<interface>> WindowListener windowClosing() windowClosed() windowOpened() windowActivated() windowClosing() windowClosed() windowOpened() windowActivated() MeinFenster addWindowListener() removeWindowListener() WindowEventHandler WindowEvent MeinFenster ... windowClosing() getWindow() ... <<interface>> WindowListener MeinFenster addWindowListener() removeWindowListener() WindowEvent getWindow() ... 37 Ereignisbehandlung 38 Ereignisbehandlung Beispiel: WindowAdapter (mit leeren Implementierungen) Beispiel: WindowAdapter (als anonymes Objekt) public class MeinWindowEventHandler extends WindowAdapter{ MeinFenster f; MeinWindowEventHandler(MeinFenster f) { this.f = f; } public void windowClosing(WindowEvent e){ f.dispose(); System.exit(0); } } public class meinFenster extends Frame { public meinFenster() { ... MeinWindowEventHandler w = new MeinWindowEventHandler(this); addWindowListener(w); ) } public class meinFenster extends Frame { public meinFenster() { ... addWindowListener(new WindowAdapter{ public void windowClosing(WindowEvent e){ dispose(); System.exit(0); } }); } 39 40 Ereignisbehandlung Ereignisbehandlung Event-Klasse Interface Methoden Ereignis- Quellen Event-Klasse Interface Methoden Ereignis- Quellen ActionEvent ActionListener actionPerformed() Button MenuItem TextField MouseEvent MouseListener Component AdjustmentEvent AdjustementListener adjustmentValueChanged() Scrollbar mouseClicked() mouseEntered() mouseExited() mousePressed() mouseReleased() ItemEvent ItemListener itemStateChanged() KeyEvent KeyListener keyPressed() keyReleased() keyTyped() Checkbox CheckboxMenuItem Choice List MouseMotionListener mouseDragged() mouseMoved() WindowEvent WindowListener Component Component windowActivated() Window windowClosed() windowClosing() windowDeactivated() windowDeiconified() windowIconified() windowOpened() 41 42 Motivation Datenbanksysteme als Basis moderner Softwaresysteme Vorlesung Informatik II Web-basierte Systeme (eBay, Amazon, Expedia, OnlineBanking) Universität Augsburg Unternehmensinformationssysteme(SAP R/3,...) Sommersemester 2011 Prof. Dr. Robert Lorenz Grundlage vieler Informatik-Berufe Administration, Planung/Entwurf, Entwicklung, Nutzung Lehrprofessur für Informatik 08. Exkurs: Datenbanken 1 2 Motivation Traditionelle Datenverwaltung Hohe Herausforderungen Verwaltung von Daten im Terabyte-Bereich (1 TB = 1000 GB) Viele Nutzer, parallele Anfragen, hohe Verfügbarkeit, Sicherheit, Konsistenz Physische Datenabhängigkeit Änderungen an der Struktur der Daten führen zu Änderungen der Anwendungsprogramme. Anwendungsprogramme müssen Struktur der Daten kennen Datenredundanz/-inkonsistenz Anwendungsprogramme/Benutzer haben spezielle Erfordernisse bzgl. der Daten: Dieselben Daten werden in verschiedenen Versionen mehrfach abgespeichert. Änderungen der Daten können zu Inkonsistenzen zwischen verschiedenen Versionen führen. Querbezüge zu anderen Informatikbereichen Modellierung, Datenstrukturen, Sicherheit, Theorie, Betriebssysteme, … 3 Traditionelle Datenverwaltung 4 Datenbanksysteme (DBS) Einbenutzerbetrieb Auf eine Datei kann nur ein Anwendungsprogramm auf einmal zugreifen. Löse Aufgaben der Beschreibung, des Abspeicherns und des Zugriffs auf Daten aus den Anwendungsprogrammen heraus. Programme Folgerungen: hohe Kosten für die Anpassung von Anwendungsprogrammen Benutzergruppen DBMS (Datenbankmanagementsystem): Verarbeitung von Anfragen, Zugriff auf gespeicherte Daten Unsicherheit bzgl. der Korrektheit der Daten Effizienzverlust bei Speicherung und Zugriff auf Daten DD (Data Dictionary) DB (Daten bank) ... DB (Daten bank) DBS (Datenbanksystem) 5 6 DBS DBS Datenbankmanagementsystem (DBMS) Softwaresystem, das die Definition, Konstruktion (Speichern) und Manipulation (Anfragen, Änderungen, Berichte) von Daten unterstützt. Eigenschaften Datenbank Menge der von einem DBMS verwalteten Daten. Sie beschreibt einen wohldefinierten Ausschnitt der realen Welt (Miniwelt). Integrierte Datenspeicherung für verschiedene Anwendungen: Unterstützung von Sichten/Views Data Dictionary/Datenbankschema (DD) Legt die Struktur der Daten fest (bzgl. eines Datenmodells). Redundanz- und Konsistenzkontrolle Datenunabhängigkeit: einheitliche Zugriffs-Schnittstelle auf Daten Schnelle Verarbeitung von DB-Operationen Mehrbenutzerbetrieb: Unterstützung von Transaktionen und Nebenläufigkeitskontrolle Datensicherheit: Zugriffsverwaltung Datenunversehrtheit: Datenwiederherstellung/Recovery 7 DBS 8 Relationales Datenmodell Kriterien für den Einsatz von DBS Jedem DBS liegt ein Datenmodell zugrunde: Es handelt sich um sehr große Datenmengen Eigenschaften der Datenelemente Struktur der Datenelemente Konsistenzbedingungen Operationen zum Speichern, Suchen, Ändern Löschen Datenverlust (nach technischen Fehlern) soll ausgeschlossen werden Das am meisten verwendete Datenmodell ist das relationale Datenmodell Anwendungen und Datenstrukturen sind Änderungen unterworfen Mehrere Benutzer/Anwendungen greifen parallel auf die Daten zu Zugriffsverwaltung ist notwendig Jetzt: Informale Einführung in dieses Datenmodell anhand von Beispielen 9 10 Relationales Datenmodell Relationales Datenmodell Nach dem relationalen Datenmodell kann man sich eine Datenbank als eine Menge von Tabellen vorstellen: Nach dem relationalen Datenmodell kann man sich eine Datenbank als eine Menge von Tabellen vorstellen: Veranstaltung ID 00001 00002 00003 ... Name Informatik 2 Java-Programmierkurs Informatik 1 ... Student Jahr 2009 2009 2010 ... Semester SS SS WS ... Matrikelnummer 1045067 ... Nachname Huber ... Vorname Markus ... ... ... ... Das ist die Sicht des Benutzers Mit der physischen Datenhaltung auf der Festplatte hat das nichts zu tun! (siehe Datenbak-Vorlesung) 11 Relationales Datenmodell 12 Relationales Datenmodell Nach dem relationalen Datenmodell kann man sich eine Datenbank als eine Menge von Tabellen vorstellen: Nach dem relationalen Datenmodell kann man sich eine Datenbank als eine Menge von Tabellen vorstellen: Daten werden zeilenweise abgespeichert Attribute Mathematisch formal ist eine Tabelle eine Relation (also eine Menge von Tupeln) Spaltennamen heißen auch Attribute – sie repräsentieren Wertemengen Relationenname Relationenschema Jede Zeile entspricht einem Tupel in dieser Relation Relation Tupel Beispiel: (0001,Informatik 2,2009,SS) ∈ Veranstaltung 13 14 Modellierung Objekt-Relationale Abbildung Zur Modellierung von relationalen Datendanken verwendet man i.d.R. Sog. Entity-Relationsship-Modell (ER-Modelle) Objekte einer Java-Anwendung lassen sich nicht direkt in einer relationalen Datenbank abspeichern ER-Modelle sind nicht Teil von UML! Wir werden im Folgenden andeuten, wie man durch Objekte verwaltete Daten in Tabellen abspeichern kann (Objektrelationale ( Abbildung) ER-Modelle haben konzepzuell eine gewisse Ähnlichkeit zu Klassendiagrammen (aber nicht grafisch!) Wir werden ER-Modelle hier nicht besprechen (siehe DatenbankVorlesung Dabei lernen Sie nebenbei etwas über Datenbank-Modellierung Details siehe Datenbank-Vorlesung 15 Objekt-Relationale Abbildung Objekt-Relationale Abbildung Beispiel: Eine Klasse (einen strukturierten Datentyp) als Tabelle abbilden Student matrikelnummer :String 16 Beispiel: Eine Klasse (einen strukturierten Datentyp) als Tabelle abbilden Student Student matrikelnummer matrikelnummer :String name name :String Student matrikelnummer 1045678 name Huber name :String Einwertige Attribute werden Spalten der Tabelle Objekte werden mit ihren Werten in Zeilen eingetragen 17 18 Objekt-Relationale Abbildung Objekt-Relationale Abbildung Beispiel: Eine Klasse (einen strukturierten Datentyp) als Tabelle abbilden Vorlesung Student matrikelnummer :String Beispiel: Eine Klasse (einen strukturierten Datentyp) als Tabelle abbilden Student matrikelnummer name name 1045678 Huber jahr name :String Vorlesung ID name 00001 Info2 jahr semester 2009 SS semester Falls eine Klasse kein Schlüsselattribut besitzt, wird ein solches hinzugefügt Künstliches Schlüsselattribut (hier: ID) In der Tabelle soll eine Spalte identifizierend sein (hier: matrikelnummer) Schlüsselattribut Werte erhält man durch Durchnummerieren. 19 Objekt-Relationale Abbildung Objekt-Relationale Abbildung Beispiel: Beliebig mehrwertige Attribute als Tabelle abbilden Student Beispiel: Endlich mehrwertige Attribute als Spalten abbilden Student Student matrikelnummer name ... 20 ... studiengang :String [1..*] studiengang :String [1..2] ... Student Studium1 Studium2 Informatik Physik Informatik null StudiengangStudent Schlüsselattribut Für jeden Wert eine Zeile matrikelnummer 1045678 1045678 1056904 studiengang Informatik Physik Mathematik 21 22 Objekt-Relationale Abbildung Objekt-Relationale Abbildung Beispiel: Assoziationen abbilden Referenzattribut Student ?..1 - ?..? – Assoziationen: Referenzattribut Referenzattribut Vorlesung ... adresse :Adresse [1] ... ID 0001 Vorlesung ... dozentID 0013 1..* <<datatype>> Adresse 1..1 dozent Professor strasse plz ... Professor ID 0013 name ... ... 23 Objekt-Relationale Abbildung 24 Objekt-Relationale Abbildung Beispiel: Assoziationen abbilden Beispiel: Generalisierungen abbilden ?..* - ?..* - Assoziationen: Eigene Tabelle Möglichkeit 1: Alle Attribute in eine einzige Tabelle unbesetzte Zellen, eine gemeinsame ID, neues Attribut typ Vorlesung ... 0..* 1..* Student ... ID 0001 Vorlesung ... <<abstract>> Person name Vorlesung_Student vorlesungID matrikelnummer 00001 1045678 Student matrikelnummer ... 1045678 25 Student Mitarbeiter matnummer persnummer Person ID name matnummer persnummertyp 26 Objekt-Relationale Abbildung Objekt-Relationale Abbildung Beispiel: Generalisierungen abbilden Beispiel: Alle Klassenattribute in eigene Tabelle abbilden Möglichkeit 2: Eigene Tabelle für jede konkrete Klasse eigene ID für jede Klasse Übernahme der Attribute abstrakter Oberklassen Klassenattribute klassenname attributname attributwert Möglichkeit 3: Eigene Tabelle für jede Klasse gemeinsame ID Zuordnung Oberklasse - Unterklasse über diese ID Beispiel: Containerklassen zur Objektverwaltung werden nicht abbgebildet, denn die verwalten ja keine eigenen fachlichen Daten 27 SQL 28 SQL Structured Query Language (SQL): Deklarative Datenbanksprache zur Definition, Manipulation und Abfrage von Daten kann interaktiv als auch eingebettet (in eine Programmiersprache) verwendet werden Einheitliche Schnittstelle für Zugriff auf Datenbanken Jetzt: kurze Einführung mit einfachen Anweisungen am Beispiel 29 Es existieren mehrere SQL-Standards, an die sich existierende DBS nicht 100-prozentig halten → Syntax variiert von DBS zu DBS Wichtige Schlüsselwörter: table record, row field, column Relation Tupel Attribut Datentypen ähnlich wie in Programmiersprachen, abhängig vom betrachteten SQL-Standard bzw. DBS 30 SQL SQL Definition einer Tabelle: create table Vorlesung ( ID integer name varchar(30) jahr char(4) semester char(2) dozent integer ); Attribute Datentypen Löschen Definition einer Tabelle: Tabellenname Ganze Zahl (4 Byte) not not not not null, null, null, null, drop table Vorlesung Variabler String der Länge <=30 String der Länge 2 not null muss Wert eingetragen sein 31 SQL 32 SQL Elementare Datentypen date Kalenderdatum float Gleitkommazahl decimal(n,m) Festkommazahl boolean Wahrheitswerte true, false array Feld (erst seit SQL-99-Standard) Einfügen von Tupeln: insert into Vorlesung values (1,‘Informatik 2‘,‘2009‘,‘SS‘,null); Undefinierter Wert für Dozent 33 34 SQL SQL Ändern von Tupeln: Löschen von Tupeln: update Vorlesung set dozentID = 13 where ID = 1; delete from Vorlesung where semester = ‘SS‘; Neuer Wert in einer Spalte Auswahl der Tupel (der Zeilen) nach einer Bedingung Auswahl der Tupel (der Zeilen) nach einer Bedingung (Mehrere set-Anweisungen durch Komma trennen) 35 SQL 36 SQL Abfrage von Tupeln: alle Tupel einer Tabelle Abfrage von Tupeln: mit Auswahl von Tupeln select * from Vorlesung; select * from Vorlesung where dozentID is null; Werte aller Spalten ausgeben Auswahl der Tupel (der Zeilen) nach einer Bedingung (Die select-Anweisung gibt immer eine Tabelle zurück) 37 38 SQL SQL Abfrage von Tupeln: mit Auswahl von Spalten Zusammengehörige Daten sind über mehrere Tabellen verstreut? Natürlicher Verbund von Tabellen (natural join) select distinct name,semester from Vorlesung; Keine Duplikate ausgeben select distinct Vorlesung.name,Professor.name from Vorlesung,Professor where vorlesung.dozentID = Professor.ID and semester = ‘SS‘; Auswahl von Spalten Verbundene Tabellen Kombination von AuswahlBedingungen (Kombination mit Tupelauswahl möglich) Auswahl von Spalten verschiedener Tabellen Identifizierung von Tupeln über Bedingung 39 40 Entwurfsprozess Der (Architektur-) Entwurf beinhaltet Vorlesung Informatik II Sommersemester 2011 Grundlegende Entwurfsentscheidungen (Teil 1) Schichtenarchitektur (Teil 1: Datenhaltung und Teil 2:GUI) Entwurfsmuster (verstreut) Prof. Dr. Robert Lorenz Standardisierung erhöht die Qualität und Wartbarkeit des Entwurfs und der Software Universität Augsburg Lehrprofessur für Informatik 9. Schichtenarchtitektur: Teil 1 (Datenhaltung) 1 2 Entwurfsprozess Entwurfsprozess Grundlegende Entwurfsentscheidungen Schichtenarchitektur GUI-Schicht Plattform Benutzeroberfläche mit Dialogführung und Darstellung der Daten der Fachkonzeptschicht Programmiersprache GUI-System Art der Datenhaltung Fachkonzeptschicht Datenhaltungschicht 3 Entwurfsprozess Funktionaler Kern der Anwendung mit Zugriff auf Datenhaltungsschicht Manipulation der fachlichen Daten Realisierung der Datenspeicherung mit Zugriff auf gespeicherte Daten 4 Entwurfsprozess Schichtenarchitektur Schichtenarchitektur: GUI-Schicht Objekte einer Schicht können jeweils nur auf Objekte der direkt unter ihr liegenden Schicht zugreifen Sichtbarmachen von fachlichen Daten an der Oberfläche durch Jede Schicht wird durch ein Paket modelliert Polling: Regelmäßiges Abfragen von Änderungen der fachlichen Daten durch die GUI-Schicht Beobachtermuster: Signalisieren von Änderungender fachlichen Daten durch die Fachkonzeptschicht (Details später) Entwurfsprozess Vorteile Wiederverwendbarkeit: jede Schicht besitzt eine präzise definierte Aufgabe und Schnittstelle Änderbarkeit/Wartbarkeit: Interne Organisation einer Schicht kann bei gleicher Schnittstelle beliebig verändert werden Datenhaltungsschicht Zur Laufzeit des Programms werden die Daten nur im Arbeitsspeicher gehalten Bei Beendigung des Programms gehen die Daten verloren Zur Vermeidung von Datenverlusten müssen die Daten dauerhaft (man sagt persistent) auf der Festplatte gespeichert werden Portabilität: Hardwareabhängigkeiten können in einer Schicht isoliert werden Datenhaltungsschicht Datenhaltungsschicht Möglichkeiten der persistenten Datenspeicherung: Kriterien für die Wahl der Datenhaltung (relationale) Datenbank Mehrbenutzersystem? Objektserialisierung Textdateien (z.B. Im XML-Format) Mehr schreibende/lesende Zugriffe? Größe der Datenmengen (passen in Arbeitsspeicher)? Datenverlust bei Systemausfall akzeptabel? Performance-Anforderungen? Zugriffsverwaltung erforderlich? Portabilität der Daten? Datenhaltungsschicht Datenhaltungsschicht Objektserialisierung: Speicherung der Gesamtheit aller Objekte als Byte-Strom mit Informationen zur Klassen, Objektbeziehungen und Attributen Textdateien: Speicherung in Textdatei als Zeichenkette in einem Format, aus dem Objekte und Objektbeziehungen rekonstruierbar sind Mehrbenutzersystem? Mehrbenutzersystem? Mehr schreibende/lesende Zugriffe? Mehr schreibende/lesende Zugriffe? Größe der Datenmengen (passen in Arbeitsspeicher)? Größe der Datenmengen (passen in Arbeitsspeicher)? Datenverlust bei Systemausfall akzeptabel? Datenverlust bei Systemausfall akzeptabel? Performance-Anforderungen? Performance-Anforderungen? Zugriffsverwaltung erforderlich? Zugriffsverwaltung erforderlich? Portabilität der Daten? Portabilität der Daten? Datenhaltungsschicht Textdateien im XML-Format: Schnittstellen mit DatenbankFunktionalitäten Mehrbenutzersystem? Datenhaltungsschicht Datenbank: wie im Exkurs zu Datenbanken beschrieben, viele verschiedene Produkte, Zugriff über standardisierte Schnittstellen (ODBC, JDBC) Mehr schreibende/lesende Zugriffe? Mehrbenutzersystem? Größe der Datenmengen (passen in Arbeitsspeicher)? Mehr schreibende/lesende Zugriffe? Datenverlust bei Systemausfall akzeptabel? Größe der Datenmengen (passen in Arbeitsspeicher)? Performance-Anforderungen? Datenverlust bei Systemausfall akzeptabel? Zugriffsverwaltung erforderlich? Performance-Anforderungen? Portabilität der Daten? Zugriffsverwaltung erforderlich? Portabilität der Daten? Datenhaltungsschicht Datenhaltungsschicht Klassendiagramm mit Datenhaltungsschicht: Anbindung an Containerklassen der Fachkonzeptschicht <Container> DatenContainer daten<Container> - uniqueInstance: DatenContainer = null -root ... -store DatenContainer -root <Container> <<interface>> Datenhaltung - DatenContainer() + instance :DatenContainer ... daten<Container> Fachkonzeptschicht Datenhaltungsschicht Datei Datenhaltungsschicht Schnittstellenoperationen zum Laden und Speichern von Daten <<interface>> Datenhaltung + + + + + Implementiere “Wurzel-Container” für alle verwalteten Daten im Singletonmuster load save add delete modify Laden und Speichern aller Objekte Speichern, Löschen und Modifizieren einzelner Objekte Müssen von jeder Daten-Speicherungs-Klasse implementiert werden Gewährleistet Austauschbarkeit der Speicherungs-Methode Datenhaltungsschicht Implementierung der Schnittstelle bei Objektserialisierung und Abspeicherung als Text (ausser XML-Format) <<interface>> Datenhaltung + + + + + load save add delete modify Laden und Speichern aller Objekte Speichern, Löschen und Modifizieren einzelner Objekte add, delete und modify werden leer implementiert oder rufen save auf Datenhaltungsschicht Implementierung der Schnittstelle bei Abspeicherung in einer Datenbank load save add delete modify Gesamtimplementierung des Ladevorgangs: Bei Start des Programms: Erzeugung eines DatenContainer-Objekts <<interface>> Datenhaltung + + + + + Datenhaltungsschicht Laden und Speichern aller Objekte Speichern, Löschen und Modifizieren einzelner Objekte save wird leer implementiert Bei Erzeugung des DatenContainer-Objekts (im Konstruktor): Erzeugung der anderen Container-Objekte und eines Datenhaltungs-Objekts Laden der Daten und Erzeugung der Objekte über das Datenhaltungs-Objekt Datenhaltungsschicht Gesamtimplementierung des Speichervorgangs: Serialisierung oder Text Bei Programmende/Benutzerbefehl/Datenänderung: Speichern aller Daten über das Datenhaltungs-Objekt (Überschreiben aller Daten) Datenbank Speichern/Modifizieren/Löschen der Daten des betreffenden Objekts über das Datenhaltungs-Objekt (Aktualisieren eines Teils der Daten) Vorlesung Informatik II Universität Augsburg Sommersemester 2011 Prof. Dr. Robert Lorenz Lehrprofessur für Informatik 10. Java: Datenhaltung mit Datenbanken 1 Datenbank-Programme Datenbank-Programme Derby (Hersteller: Apache Foundation) MySQL Für die lokale Installation auf ihrem Rechner Download von Datenbank und Treiber (jar-Datei): http://db.apache.org/derby/ Haben wir auf unserem Server installiert (aioml.informatik.uni-augsburg.de): Nur erreichbar über Uni-Netz oder VPN-Verbindung Download des Treibers (jar-Datei): http://www.mysql.com/products/connector/j/ Datei entpacken und Pfad merken Pfad im Classpath eintragen: java –Xbootclasspath/a: <Pfad der jar-Datei> Datei entpacken und Pfad merken Pfad im Classpath eintragen: java –Xbootclasspath/a: <Pfad der jar-Datei> Beim ersten Programmstart muss man Tabellen erzeugen -(create-Anweisung) Bei erneutem Start stehen diese Tabellen zur Verfügung. Tabellen zum Abfragen sind angelegt (keine neuen Tabellen anlegen!) 2 3 ODBC - Schnittstelle JDBC - Schnittstelle Open Database Connectivity (ODBC) Java Database Connectivity (JDBC) Für alle kommerziellen und freien DBMS gibt es die einheitliche, standardisierte Benutzerschnittstelle ODBC Für den Zugriff über Java-Programme existiert die entsprechende Schnittstelle JDBC ODBC verwendet SQL Das Paket java.sql stellt Klassen für den Zugriff auf Datenbanken über ihre JDBC-Schnittstelle bereit Der ODBC-Treiber eines DBMS bietet eine ProgrammierSchnittstelle (API) für C-Programme Über diese Schnittstelle können wir einheitlich sowohl auf die Derby-, als auch auf die MySQL-Datenbank zugreifen! Über ODBC kann eine Anwendung eine Datenbank unabhängig von ihrer Implementierung über SQL-Befehle verwaltet werden 4 5 Das Paket java.sql Das Paket java.sql Schritt 1: Laden einer JDBC-Treiber-Klasse (DB-spezifisch) Schritt 1: Laden einer JDBC-Treiber-Klasse (DB-spezifisch) Klassenoperation der Klasse Class: Class.forName( “org.apache.derby.jdbc.EmbeddedDriver”); static Class forName(String className) A call to forName("X") causes the class named X to be initialized. Returns: Class object for the class with the specified name. Class.forName(“com.mysql.jdbc.Driver”); className fully qualified name of the desired class. Class Metaklasse zur Verwaltung von Datentypen 6 Das Paket java.sql 7 Das Paket java.sql Schritt 2: Verbindung zur DB herstellen (DB-spezifisch) Schritt 2: Verbindung zur DB herstellen (DB-spezifisch) Klassenoperation der Klasse DriverManager Connection c = DriverManager.getConnection( “jdbc:derby:derbyDB;create=true”,””,””); static Connection getConnection(String url, String User, String password) Attempts to establish a connection to the given database URL. Attempts to select a driver from the set of registered JDBC drivers. url DriverManager Connection c = DriverManager.getConnection( “jdbc:mysql://aioml.informatik.uniaugsburg.de:3306/theDatabase”,”user”,”password”); a database url of the form jdbc:subprotocol:subname Verwaltet geladene Treiber-Klassen 8 9 Das Paket java.sql Das Paket java.sql Schritt 3: Anweisungs-Objekt für SQL-Anfragen (einheitlich!) Schritt 3: Anweisungs-Objekt für SQL-Anfragen (einheitlich!) Operation der Schnittstelle Connection Statement abfrage = c.createStatement(); Statement createStatement() Creates a Statement object for sending SQL statements to the database. Connection A connection (session) with a specific database. SQL statements are executed within the context of a connection. 10 Das Paket java.sql 11 Das Paket java.sql Schritt 4: SQL-Anweisung ausführen (einheitlich!) Schritt 4: SQL-Anweisung ausführen (einheitlich!) Operationen der Schnittstelle Statement Operationen der Schnittstelle Statement ResultSet executeQuery(String query) boolean execute(String sql) executes the given SQL statement, returns a single ResultSet object. executes the given SQL statement, which may return multiple results. ResultSet contains the data produced by the given query; never null Statement The object used for executing a static SQL statement and returning the results it produces. 12 use getResultSet,getMoreResults to get the result(s). 13 Das Paket java.sql Das Paket java.sql Schritt 4: SQL-Anweisung ausführen (einheitlich!) Schritt 4: SQL-Anweisung ausführen (einheitlich!) Operationen der Schnittstelle Statement Operationen der Schnittstelle Statement int executeUpdate(String sql) ResultSet getResultset() executes INSERT, UPDATE, or DELETE statements Returns data from previous execute Returns: the row count for statement 14 Das Paket java.sql 15 Das Paket java.sql Schritt 4: SQL-Anweisung ausführen (einheitlich!) Tabelle kreieren: String befehl = “CREATE TABLE ‘Vorlesung’ ( ‘ID’ INTEGER NOT NULL, ‘Name’ VARCHAR(20) NOT NULL, ‘Jahr’ CHAR(4) NOT NULL, ‘Semester’ CHAR(2) NOT NULL, ‘DozentID’ INTEGER)”; Operationen der Schnittstelle Statement void close() Releases database and JDBC resources abfrage.execute(befehl); (Hochkommas bei Bezeichnern, Unterscheidung Gross/KleinSchreibung) 16 17 Das Paket java.sql Das Paket java.sql Tupel einfügen: Tupel löschen: String befehl = “INSERT INTO Vorlesung VALUES (1,‘Informatik 2‘,‘2009‘,‘SS‘,null)”; String befehl = “DELETE FROM Vorlesung WHERE semester = ‘SS’”; abfrage.executeUpdate(befehl); abfrage.executeUpdate(befehl); (Hochkommas bei Zeichenketten, nicht bei Zahlen, nicht bei null) 18 Das Paket java.sql 19 Das Paket java.sql Tupel ändern: Tupel ausgeben: String befehl = “UPDATE Vorlesung SET DozentID = 13 WHERE ID = 1”; String befehl = “SELECT * FROM Vorlesung”; ResultSet ergebnis = abfrage.executeQuery(befehl); abfrage.executeUpdate(befehl); 20 21 Das Paket java.sql Das Paket java.sql Tupel ausgeben: Tupel ausgeben: Schnittstelle ResultSet Schnittstelle ResultSet A table of data representing a database result set Maintains a cursor pointing to its current row of data (initially 1st row) Vorwärts/Rückwärts durchlaufbar und aktualisierbar machen durch Aufruf anderer Version von createStatement unter Benutzung geeigneter Konstanten: Default: not updatable, has a cursor that moves forward only. Statement stmt = c.createStatement( ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE); ResultSet rs=stmt.executeQuery("..."); 22 Das Paket java.sql 23 Das Paket java.sql Tupel ausgeben: Tupel ausgeben: Schnittstelle ResultSet Schnittstelle ResultSet Operationen zur Positionierung des Cursors: Operationen, um Daten zu lesen (für jeden Datentyp): boolean absolute(int row) void moveToInsertRow() void moveToCurrentRow() boolean first() boolean last() boolean next() boolean previous() boolean getBoolean(int columnIndex) boolean getBoolean(String columnName) ... 24 25 Das Paket java.sql Das Paket java.sql Tupel ausgeben: Tupel ausgeben: Schnittstelle ResultSet String befehl = “SELECT * FROM Vorlesung”; Operationen, um Daten zu aktualisieren (für jeden Datentyp): void ... void void void updateBoolean(int columnIndex, boolean x) insertRow() updateRow() deleteRow() ResultSet ergebnis = abfrage.executeQuery(befehl); while (ergebnis.next()){ System.out.println(ergebnis.getString(“Name”)); //oder Operationen zum Erzeugen von Objekten } 26 Das Paket java.sql 27 Das Paket java.sql Zusammenfassung des Codes: Zusammenfassung des Codes: Programmabbruch bei Fehler Class.forName(“org.apache.derby.jdbc.EmbeddedDriver”); Class.forName(“org.apache.derby.jdbc.EmbeddedDriver”); Connection c = DriverManager.getConnection( “jdbc:derby:derbyDB;create=true”,””,””); Connection c = DriverManager.getConnection( Kein Treiberzugriff “jdbc:derby:derbyDB;create=true”,””,””); Statement abfrage = c.createStatement(); Statement abfrage = c.createStatement(); String befehl = “SELECT * FROM Vorlesung”; ResultSet ergebnis = abfrage.executeQuery(befehl); String befehl = “SELECT * FROM Vorlesung”; ResultSet ergebnis = abfrage.executeQuery(befehl); while (ergebnis.next()){ //Operationen zum Erzeugen von Objekten } Kein Datenbankzugriff while (ergebnis.next()){ //Operationen zum Erzeugen von Objekten } Klasse nicht vorhanden 28 29 Das Paket java.sql Das Paket java.sql Einfügen in Datenhaltungsschicht: Klassendiagramm Zusammenfassung des Codes: Fehler abfangen try{ Class.forName(“org.apache.derby.jdbc.EmbeddedDriver”); <Container> -daten<Container> Connection c = DriverManager.getConnection( “jdbc:derby:derbyDB;create=true”,””,””); -root Statement abfrage = c.createStatement(); DatenContainer -store -root String befehl = “SELECT * FROM Vorlesung”; ResultSet ergebnis = abfrage.executeQuery(befehl); <Container> <<interface>> Datenhaltung -daten<Container> while (ergebnis.next()){ //Operationen zum Erzeugen von Objekten } }catch(Exception e){<Code für Fehlerbehandlung>} Datei 30 Das Paket java.sql Das Paket java.sql Einfügen in Datenhaltungsschicht: Klassendiagramm + + + + + <<interface>> Datenhaltung load save add delete modify 31 Einfügen in Datenhaltungsschicht (eine Alternative): Klassendiagramm Datei - DriverClassName :String =... - databaseUrl :String =... con :Connection user :String password :String Laden und Speichern aller Objekte Speichern, Löschen und Modifizieren einzelner Objekte + + + + + + 32 Datei() load(out con :DatenContainer) save(in con :DatenContainer) add(in o :Object) delete(in o :Object) modify(in o :Object) 33 Das Paket java.sql Das Paket java.sql Einfügen in Datenhaltungsschicht (eine Alternative): Implementierung in Java Einfügen in Datenhaltungsschicht (eine Alternative): Implementierung in Java public Datei() { try{ Class.forName(driverClassName); public void load(DatenContainer con){ try{ Statement abfrage = con.createStatement(); String befehl = <Select-Ausdruck passend zu Klasse>; ResultSet ergebnis = abfrage.executeQuery(befehl); while (ergebnis.next()){ <Objekte erzeugen in Containern über dataCon> } }catch(Exception e){ <Code für Fehlerbehandlung> } } con = DriverManager.getConnection (databaseUrl,user,password); }catch(Exception e){ <Code für Fehlerbehandlung> } } [Bei mehreren Klassen: viele select-Anweisungen nacheinander] 34 35 Das Paket java.sql Das Paket java.sql Daten aus Datenbank laden Einfügen in Datenhaltungsschicht (eine Alternative): Implementierung in Java AnwendungsGUI starten public void add(Oblect o){ try{ Statement abfrage = con.createStatement(); In AnwendungsGUI DatenContainer initialisieren In DatenContainer Objekt-Container initialisieren String befehl = <insert-Ausdruck passend zu o>; In DatenContainer Datei-Objekt store initialisieren und store.load(this) aufrufen abfrage.executeUpdate(befehl); }catch(Exception e){ <Code für Fehlerbehandlung> } } [Bei mehreren Klassen: Viele alternative insert-Anweisungen] 36 37 Das Paket java.sql Das Paket java.sql Neues Objekt in Datenbank speichern Verwaltung der Werte der (zusätzlichen) ID-Spalten? “Speichern”-Button klicken Zusätzliche ID-Attribute in den Fachkonzeptklassen (Vor-/Nachteile?) In actionPerformed(): Objekt erzeugen und in ObjektContainer einfügen Im Container: Aufruf von root.getStore().add(o) Übernehmen der Werte beim Laden/Abspeichern Wie stellt man die Eindeutigkeit der ID-Werte sicher? ID-Attribut in der Fachkonzeptschicht verwenden? Identifizieren von Tupeln in Tabellen über die ID 38 39 Das Paket java.sql Verwaltung der Werte der (zusätzlichen) ID-Spalten? Vorlesung Informatik II Keine solchen zusätzlichen Attribute (Vor-/Nachteile?) Universität Augsburg Erzeugung der Werte beim Abspeichern (Datenhaltung) Ignorieren der ID-Werte beim Laden Wie identifiziert man Tupel in Tabellen? Wie stellt man die Eindeutigkeit der ID-Werte sicher? Sommersemester 2011 Prof. Dr. Robert Lorenz Lehrprofessur für Informatik 11. UML: Sequenzdiagramm 40 1 Motivation Sequenzdiagramme Es gibt verschiedene UML-Diagramme, um (noch programmiersprachenunabhängig) die Implementierung von Operationen zu modellieren Sequenzdiagramme veranschaulichen den Ablauf eines Teils der Anweisungen bei Abarbeitung einer Operation Sequenzdiagramme: Berücksichtigen Nebenläufigkeit (kausale Unabhängigkeit) von Anweisungen Einfachster Fall: Nur ein alternativer Ablauf ohne Verzweigungen und Wiederholungen wird modelliert Verallgemeinerungen: Mehrere alternative Abläufe zusammenfassen (mittels Verzweigungen und Wiederholungen) Zustandsautomaten Aktivitätsdiagramme 2 Sequenzdiagramme 3 Sequenzdiagramme Sequenzdiagramme zeigen grafisch die Interaktion zwischen mehreren Kommunikationspartnern Komponenten eines Sequenzdiagramms: Kommunikationspartner Aufrufer (Sender) und Ausführer (Empfänger) von Operationen Angegeben durch ihren Namen in einer rechteckigen Box Kommunikationspartner: Objekte, Klassen, Benutzer Klassen: benutze Klassennamen Objekte: benutze Objektnamen oder :<Klassenname> (anonymes Objekt) Benutzer hat den Namen Benutzer (User) Interaktionen: Operationsaufrufe und Signale (Botschaften) Synchrone Botschaften: Sender wartet mit der eigenen Verarbeitung auf Beendigung der aufgerufenen Operation Nach unten verlaufenden Lebenslinien ausgehend von jedem Kommunikationspartner Stellt Existenzzeit eines Kommunikationspartners dar Angegeben durch gestrichelte Linien Asynchrone Botschaften: Sender wartet nicht mit der eigenen Verarbeitung auf Beendigung der aufgerufenen Operation Parallele Verarbeitung 4 5 Sequenzdiagramme Sequenzdiagramme Komponenten eines Sequenzdiagramms: Komponenten eines Sequenzdiagramms: Botschaften Angegeben durch durchgezogenen Pfeil von Lebenslinie des Senders zur Lebenslinie des Empfänger Synchrone Botschaft Durchgezogener Pfeil mit geschlossener Pfeilspitze Rückantwort erforderlich Botschaft kausal vor (oberhalb von) Rückantwort Annotiert mit dem Namen (Operation: Benutze Prototyp) Rückantwort Gestrichelter Pfeil mit geschlossener Pfeilspitze Operationen: annotiert mit Rückgabeobjekt Werden von oben nach unten an die Lebenslinien notiert Interpretation: Obere Botschaft kausal vor unterer Botschaft Asynchrone Botschaft: Durchgezogener Pfeil mit offener Pfeilspitze 6 Sequenzdiagramme 7 Sequenzdiagramme Komponenten eines Sequenzdiagramms: Komponenten eines Sequenzdiagramms: Operationsabarbeitungsdauer Angegeben durch rechteckige Box, über die Lebenslinie gelegt Anweisungen, die keiner Botschaft entsprechen, können nicht modelliert werden, z.B. Erlaubt Darstellung, dass bei der Abarbeitung einer Operation andere Operation aufgerufen werden Deklarationen Wertzuweisungen an Variablen primitiven Typs … Später: Kontrollstrukturen (Verzweigung, Wiederholung) 8 9 Sequenzdiagramme Sequenzdiagramme Botschaften: Beispiele Operationsaufrufe und Kommunikationspartner Synchrone Botschaften: Verwaltungsoperationen Ausnahmebehandlung (später) Empfänger ist dasjenige Objekt/diejenige Klasse, für das/die die Operationen aufgerufen wird Die Operation gehört zum Verhalten des Objekts/der Klasse Empfänger von Klassenoperationen sind Klassen Empfänger sonstiger Operationen sind Objekte Asynchrone Botschaften: Konstruktoren Benutzeraktionen (Ereignisse) Aufrufe von Prozessen (später) Sender ist dasjenige Objekt/diejenige Klasse, bei dem eine Operationsabarbeitung den Operationsaufruf verursacht Sender ist eine Klasse bei Abarbeitung einer Klassenoperation Sender ist ein Objekt bei Abarbeitung sonstiger Operationen 10 Sequenzdiagramme Sequenzdiagramme Allgemeine grafische Veranschaulichung <Partner> Lebenslinie <Partner> <synchron> <synchron> Beispiel: ActionListener registrieren (Teil der Implementierung des Konstruktors des Fensters) <Partner> User Aufruf bei Abarbeitung <asynchron> <Rückgabeobjek> 11 new MeinFenster() Botschaft an sich selbst :MeinFenster close:Button new Button() add(close) <synchron> addActionListener(this) <asynchron> <asynchron> <synchron> Operationsabarbeitungsdauer 12 13 Sequenzdiagramme Sequenzdiagramme Beispiel: Auf ActionEvent reagieren (zeigt eine alternative Ausführung) User :Button :MeinFenster onClick new ActionEvent() Beispiel: Daten von der GUI in die Fachkonzeptklasse übertragen (Ausschnitt) User speichern:Button :MeinFenster onClick new ActionEvent() System e:ActionEvent e:ActionEvent actionPerformed(e) actionPerformed(e) getActionCommand() s getActionCommand() s new Student() subject:Student save() name:TextField getText() s setName(s) dispose() exit(0) 14 Sequenzdiagramme 15 Sequenzdiagramme Kausalität in Sequenzdiagrammen: Abstraktion in Sequenzdiagrammen: Senden vor Empfangen von Nachrichten Operationsbeginn vor Operationsende Obere vor untere Aktion Modellierung in mehreren Phasen: Operationen werden Top-Down verfeinert / implementiert Nicht kausal geordnete Aktionen sind kausal unabhängig Solche Aktionen heißen nebenläufig 16 17 Sequenzdiagramme Sequenzdiagramme Darstellung verschachtelter Operationsaufrufe der Form <methodeAussen>(<methodeInnen>())(Übergabe von Parametern durch Operationsaufruf) Darstellung verschachtelter Operationsaufrufe der Form <methodeAussen>(<methodeInnen>())(Übergabe von Parametern durch Operationsaufruf) Alternative 1: Verzichte auf Darstellung von <methodeInnen>() Alternative 2: Zerlege Anweisung in zwei Botschaften <Partner> <Partner> <Partner> <methodeAussen>(<methodeInnen>()) <Partner> <Partner> <methodeInnen>() o <methodeAussen>(o) 18 Sequenzdiagramme 19 Sequenzdiagramme Konsistenz mit Klassendiagramm beachten: Es gibt etliche Operatoren zur Kombination von Sequenzdiagrammen: Alle Klassen von Kommunikationspartnern müssen im Klassendiagramm vorkommen Alternativen Alle Operationen müssen in der richtigen Klasse im Klassendiagramm vorkommen Wiederholungen Operationen dürfen nur konsistent zu den Navigierbarkeiten der Assoziationen im Klassendiagramm aufgerufen werde (Wer eine Operation eines Objekts aufruft, muss dieses Objekt kennen!) u.v.m. … Oft muss das Klassendiagramm nochmal angepasst werden 20 21 Sequenzdiagramme Sequenzdiagramme Alternative: alt-Umgebung zur Unterscheidung mehrerer alternativer Ausführungen in Abhängigkeit von Bedingungen <Partner> alt <Partner> Alternative: opt-Umgebung zur optionalen Ausführung in Abhängigkeit von einer Bedingung <Partner> <Partner> <Partner> <Partner> <botschaft> <botschaft> [Bedingung1] <botschaft> opt <botschaft> <botschaft> <botschaft> <botschaft> <botschaft> [Bedingung] [Bedingung2] 22 Sequenzdiagramme 23 Sequenzdiagramme Beispiel: Auf ActionEvent reagieren :Button :MeinFenster onClick new ActionEvent() Wiederholung: loop-Umgebung für n-fache Wiederholung User System <Partner> <Partner> <Partner> e:ActionEvent <botschaft> actionPerformed(e) getActionCommand() s opt [s.equals(“close“)] loop(n) dipose() <botschaft> <botschaft> <botschaft> exit(0) 24 25 Sequenzdiagramme Sequenzdiagramme Wiederholung: loop-Umgebung für Wiederholung in Abhängigkeit von einer Bedingung <Partner> <Partner> Beispiel: Akualisierung eines Containers und der GUI nach Datenspeicherung :MeinFenster <Partner> professoren:ProfessorenContainer <botschaft> addProfessor(subject) loop <botschaft> update() professorenListe:List removeAll() <botschaft> <botschaft> getProfessor(k++) p loop p:Professor [Bedingung] toString() s add(s) [0<=k<anzahlProfessoren] 26 27 GUI-Schicht Sichtbarmachen von fachlichen Daten an der Oberfläche Vorlesung Informatik II Polling: Regelmäßiges Abfragen von Änderungen der fachlichen Daten durch die GUI-Schicht Universität Augsburg Sommersemester 2011 Beobachtermuster: Signalisieren von Änderungen der fachlichen Daten durch die Fachkonzeptschicht Prof. Dr. Robert Lorenz Lehrprofessur für Informatik 12. UML – GUI-Schicht 1 2 GUI-Schicht GUI-Schicht Sichtbarmachen von fachlichen Daten an der Oberfläche Beobachtermuster: Klassendiagramm (grün: API) Bisher: Anzeige von Daten nur durch ein Fenster möglich, das sich selbst aktualisiert Sorgt dafür, dass bei Änderung eines Objekts alle davon abhängigen Objekte benachrichtigt und automatisch aktualisiert werden Jetzt: Anzeige von Daten simultan in mehreren Fenstern möglich. Aktualisierung aller Fenster durch Implementierung des Beobachtermusters (Polling später) 3 GUI-Schicht GUI-Schicht Beobachtermuster: Klassendiagramm (grün: API) <<interface>> Observer update(o :Observable, arg :Object) GUIKlasse update(o :Observable, arg :Object) 4 Beobachtermuster: Schnittstelle Oberserver GUI-Klasse implementiert Observer-Schnittstelle Observable 0..* observers 1..* notifyObservers() setChanged() addObserver() deleteObserver() subject 0..* 1..1 update(o:Observable,arg:Object): aktualisiert angezeigte Daten von o DatenKlasse 5 6 GUI-Schicht GUI-Schicht Beobachtermuster: Klasse Observable Beobachtermuster: Sequenzdiagramm User Daten-Klasse erbt von Observable-Klasse und kann dann folgende Operationen benutzen: new GUIKlasse() subject:DatenKlasse notifyObservers() Startet Aktualisierung aller Observer-Objekte ... addObserver(this) deleteObserver() Löscht Verbindung zu Observer-Objekt addObserver() g:GUIKlasse Baut Verbindung zu Observer-Objekt auf setChanged() Teilt mit, dass eine Veränderung des Observable-Objekts stattgefunden hat changeDaten() ... setChanged() notifyObservers() update(subject,null) ... loop [g in observers] 7 Dialogstruktur 8 Dialogstruktur Bisher: Ein Fenster zum Erfassen, Ändern und Anzeigen von Daten Erfassungsfenster Erstelle für jede Klasse des Fachkonzepts ein Erfassungsfenster Jetzt: zum Erfassung und Ändern von Objekten (Attribute und Beziehungen) Ein Fenster für das Anzeigen von Daten Ein anderes Fenster für das Erfassen und Ändern von Daten Vorschlag für eine Systematisierung der gegenseitigen Aufrufe von Fenstern (Dialogstruktur) 9 Grafisches Interaktionselement für jedes Atribut und jede Beziehung Schaltflächen oder pop-up-Menü-Einträge für Operationen 10 Dialogstruktur Dialogstruktur Erfassungsfenster Erstelle für jede Klasse des Fachkonzepts ein Erfassungsfenster Erfassungsfenster Erstelle für jede Klasse des Fachkonzepts ein Erfassungsfenster Standardschaltflächen: 1-Assoziationen Speichern des Objekts und Schließen des Fensters Ok Übernehmen Speichern ohne Schließen des Fensters *-Schaltfläche: öffnet Erfassungsfenster der assoziierten Klasse, Verbindung mit neu erfasstem Objekt Abbrechen Schließen und Verwerfen der Eingabe Liste wie ein als zusätzliches Attribut aufnehmen ...-Schaltfläche: öffnet Auswahlliste der assoziierten Klasse, Verbindung mit selektiertem Objekt Öffnen des zugehörigen Listenfensters 11 Dialogstruktur 12 Dialogstruktur Erfassungsfenster Erstelle für jede Klasse des Fachkonzepts ein Erfassungsfenster Erfassungsfenster Erstelle für jede Klasse des Fachkonzepts ein Erfassungsfenster *-Assoziationen Sonderfall Generalisierungen als zusätzliche Liste aufnehmen Bei konkreter Oberklasse: Erfassungsfenster für Oberklasse und jede Unterklasse. Zugriff auf alle geerbten Attribute in Erfassungsfenstern für die Unterklassen *-Schaltfläche: öffnet Erfassungsfenster der assoziierten Klasse, neu erfasstes Objekt Liste hinzufügen bei abstrakter Oberklasse: kein Erfassungsfenster für Oberklasse. Zugriff auf alle geerbten Attribute im Erfassungsfenster für die Unterklassen ...-Schaltfläche: öffnet Auswahlliste der assoziierten Klasse, selektiertes Objekt Liste hinzufügen x-Schaltfläche: Löscht Verbindung mit selektiertem Objekt [analog bei mehrstufiger Generalisierung] Bei mehreren Assoziationen: Ein Register pro Assoziation 13 14 Dialogstruktur Dialogstruktur Erfassungsfenster Erstelle für jede Klasse des Fachkonzepts ein Erfassungsfenster Erfassungsfenster Erstelle für jede Klasse des Fachkonzepts ein Erfassungsfenster Anbindung an Fachkonzeptklassen Anbindung an Fachkonzeptklassen Erfassungsfenster kennt zugehörige Fachkonzeptklasse mit Container und kann auf deren Attribute und Operationen zugreifen, aber nicht umgekehrt. DatenKlasseContainer 1..1 meineObjekte Anbindung durch 1-zu-1-Assoziation GUIErfassung subject 0..1 0..* DatenKlasse 1..1 15 Dialogstruktur Dialogstruktur Erfassungsfenster Erstelle für jede Klasse des Fachkonzepts ein Erfassungsfenster Standard-Operationen save() Übergabe der Eingabedaten an subject update() Lesen und Darstellen der subject-Daten onOk() OnÜbernehmen() OnAbbrechen() OnListe() 16 Erfassung eines Objekts: Sequenzdiagramm User ok:Button :GUIErfassung onClick new ActionEvent() e:ActionEvent actionPerformed(e) getActionCommand() s onOk() new DatenKlasse() save() Operationen zu Schaltflächen subject set...() ... 17 18 Dialogstruktur Dialogstruktur Listenfenster Erstelle für jede Containerklasse des Fachkonzepts ein Listenfenster Listenfenster Erstelle für jede Containerklasse des Fachkonzepts ein Listenfenster Anzeige aller Objekte einer Klasse mit den wichtigsten Attributen in einer Liste / Tabelle Standardschaltflächen: Neu Öffnen eines leeren Erfassungsfensters grafisches Interaktionselement für jedes Klassenattribut Ändern Erfassungsfenster für selektiertes Objekt Löschen Löschen des selektierten Objekts Schaltflächen oder pop-up-Menü-Einträge für Klassenoperationen Schließen Schließen des Listenfensters 19 Dialogstruktur 20 Dialogstruktur Listenfenster Erstelle für jede Containerklasse des Fachkonzepts ein Listenfenster Listenfenster Erstelle für jede Containerklasse des Fachkonzepts ein Listenfenster Anbindung an Fachkonzeptklassen Anbindung an Fachkonzeptklassen Listenfenster-Klasse kennt zugehörige Containerklasse, aber nicht umgekehrt <<interface>> Observer 1..* 0..* observers Observable Anbindung über *-zu-1-Assoziation Benutzung des Bobachtermusters, um simultanes Anzeigen in mehreren Fenstern zu erlauben 21 GUIListe alleDaten 0..* 1..1 DatenKlasseContainer 22 Dialogstruktur Dialogstruktur Listenfenster Erstelle für jede Containerklasse des Fachkonzepts ein Listenfenster Erfassung eines Objekts und Listenfenster aktualisieren: Sequenzdiagramm :GUIErfassung Standardoperationen update() Containers actionPerformed(e) onOk() new DatenKlasse() save() Auslesen und Darstellen aller Objekte des OnNeu() OnÄndern() OnLöschen() OnSchließen() :DatenKlasseContainer subject set...() Operationen zu Schaltflächen addDaten(subject) setChanged() notifyObservers() 24 23 Dialogstruktur Dialogstruktur Mögliche Erweiterungen/Verallgemeinerungen: Darstellung als Zustandsautomat für eine Objekt-Art Mögliche Erweiterungen/Verallgemeinerungen: Eigene Fenster für: Zustand: Aktiviertes Fenster uebernehmen Erfassung eines neuen Objekts (Kern-Attribute, keine Beziehungen) erfassen Liste zur Auswahl eines Objekts für Erfassung (Übernahme von Attributwerten) Liste zur Auswahl eines Objekts für Aufbau von Objektbeziehungen starten ok|abbrechen Programm liste Modifizierung eines Objekts (alle Attribute und Beziehungen) Auswahl liste beenden Liste zur Auswahl eines Objekts für Löschen/Änderungen ok|abbrechen Erfassung ok|abbrechen Liste Zustandübergang: Aktionsname aendern Modifizierung ok|abbrechen loeschen 25 26 3-Schichtelmodell gesamt <<interface>> Observer GUIListe 1..* 0..* observers alleDaten 0..* 1..1 Observable DatenKlasseContainer meineObjekte GUIErfassung <<interface>> Datenhaltung subject 0..1 store 0..1 1..1 1..1 1..1 0..* DatenKlasse 1..1 DatenContainer Datei 27