Einführung in die Objektorientierte Programmierung
MVC mit Zustandsbasierter Modellierung
23.04.2009Helmut Paulus Max-Planck-Gymnasium
Trier
Einstieg
2
Diskussion: Nachteile der bisher im Unterricht entwickelten Verschlüsselungsverfahren
leichte Entschlüsselung möglich
Ziel: bessere Verfahren nutzen evtl. Quellecode von anderen in eigene Programme einbinden, möglichst ohne Aufwand
Wünschenswert wäre • Bereits implementierte Verfahren nutzen (soweit sie zur Verfügung stehen)• Einbau ins eigene Programm möglichst einfach,
z. B. als Klasse wie die Delphi-Komponenten
Grundsätzliche Schwäche der bisher entwickelten Programme• Der Quellcode ist in eine GUI integriert• Wiederverwendbarkeit ist nicht nicht ohne Aufwand gegeben
Lösung: Objektorientierte Programmierung
Verwendung einer vorgegeben Klasse (2)
3
• Lesen und Analysieren einer Klassendokumentation
• Klärung der zur Verfügung gestellten Dienste
Die Klasse TCaesar als Bauplan für Verschlüsselungsobjekte
Objekte vom Typ TCaesar stellen Dienste zur Verfügung:
• Aufträge• Anfragen
Die nächsten Schritte
• Entwicklung (oder Vorgabe) eines Rahmenprogramms
• Experimente mit dem Programm
z. B.: Der Versuch, einen Dienst der Klasse zu nutzen scheitert, typische Fehlermeldung, Ursache: noch kein Objekt vorhanden, das den Dienst ausführen könnte
Arbeiten mit Klassen
4
Erarbeitung eines Grundschemas zum Arbeiten mit vorgegebenen Klassen
• Vorbereitung:Klasse integrieren, Objektbezeichner deklarieren
• Verwendung:Objekt erzeugen, Dienste des Objekts nutzen, Objekt vernichten
uses
Windows,…, mTCaesar;
type
TGUI = class(TForm)
BEntschluesseln: TButton;
BEntschluesseln: TButton;
procedure BVerschluesselnClick();
procedure BEntschluesselnClick();
procedure FormCreate();
procedure FormDestroy();
private
{ Private-Deklarationen }
Caesar : TCaesar;
public
{ Public-Deklarationen }
end;
Vorbereitung:
Einbinden der Unit
Objektbezeichner(-Variable) deklarieren
Implementierung in Delphi
Objekte verwenden
5
Mit dem Objekt arbeiten:
procedure TGUI.FormCreate();
begin
Caesar := TCaesar.Create;
end;
Objekt erzeugen(z. B. ereignisgesteuert)
procedure TGUI.FormDestroy();
begin
Caesar.Free;
end;
Objekt vernichten(z. B. ereignisgesteuert)
procedure TGUI.BVerschluesselnClick();
var
Quelltext, Geheimtext : string;
begin
// Eingabe
Quelltext := MText.Text;
// Verarbeitung
Geheimtext := Caesar.getVerschluesselt(QuellText);
// Ausgabe
MText.Text := Geheimtext;
end;
Verschlüsselungsdienst des Objekts nutzen
Vertiefung des Objektverständnisses
Objekt als
• Einheit aus Attributen und Methoden, zuständig für die Erledigung bestimmter Aufgaben
• aktive und autonome Programmeinheit (Modul), die Aufgaben erledigt
Klasse:
• Bauplan für Objekte, der für die Erzeugung von Objekten benötigt wird
Diskussion:
• Vorteile des Objekt-Konzepts: Geheimnisprinzip, Modularisierung
• Verdeutlichung durch einen Austausch der Klasse (z. B. TVigener)
6
Übungen zur Verwendung von Klassen (2)
Beispiel:Verwenden einer Klasse zur Ermittlung von Buchstabenhäufigkeiten in TextenTTextAnalysator
Aufbau und Implementierung einer Klasse (2)
Analyse einer vorher benutzten Klasse (z. B.: TCaesar)
Eine Klassen-Deklaration besteht aus Deklarationen von
– Attributen für die verschiedenen Eigenschaftender Objekte,
– Konstruktoren zur Erzeugung und Initialisierung der Objekte,
– Methoden, d.h. Operationen (Algorithmen) auf Objekten.
7
Beschreibung der Klassenstrukturmit einem UML-Klassendiagramm
TCaesar = class
private //Attribute
Schluessel : integer;
public //Methoden
constructor create;
procedure SetSchluessel (…);
function getSchluessel : integer;
function getVorbereitet (…) : string;
function getEntschluesselt(…) : string;
function getVerschluesselt (..) : string;
end;
Implementierung in Delphi
Hinweise zur Implementierung: • Jede Klasse sollte in einer separaten Datei des entsprechenden Namens stehen.• Klassendeklaration im Interface-Teil, Quellcode im Implementation-Teil der Klassenunit• Die Schlüsselworte private bzw. public klassifizieren, für wen die entsprechenden Elemente zugänglich sind. • Innerhalb einer Objekt-Methode/eines Konstruktors kann auf die Attribute des Objekts direkt zugegriffen werden.
Darstellung objektorientierter Modelle
8
Das UML-Klassendiagramm des Chiffiersystems zeigt den Aufbau der Anwendung und die Beziehungenzwischen den Objekten. Das Diagramm ist statisch, es werden keine Programmabläufe sichtbar.
Das Formular vom Typ TGUI verwaltet die Objekte Caesar und Analysator, d. h. es ist zuständig für deren Erzeugung und Vernichtung. (hat-Beziehung)
Die Diagramme sind unabhängig von der Programmiersprachen!
Vererbung
9
Vererbung:
• Jedes Formular besitzt "von Anfang an" gewisse Eigenschaften, die dieses spezielle Formular (Klasse TForm1) von einer Oberklasse (Klasse TForm) geerbt hat.
• Mit Hilfe des Vererbungsmechanismus kann man existierende Klassen erweitern, d. h. neue Eigenschaften und Operationen hinzufügen.
Beispiel:Die Klassen TCaesar und TVigenere haben gemeinsame Schnittstellen, könnten also aus einer gemeinsamenOberklasse abgeleitet werden.
KlassenhierarchieBei Delphi sind alle Objekte Nachfahren eines Urobjekts - Klasse TObject. In der Klasse TObject wird das grundlegende Verhalten, das allen Objekten in Delphi gemeinsam realisiert. (Z. B. Standardkonstruktor, Destructor …)
Jede objektorientierte Programmierumgebung stellt eine Klassenbibliothek zur Verfügung, deren Klassen hierarchisch angeordnet sind.
Delphi‘s Klassenhierarchie
10
11
Entwicklung eines objektorientierten Modells
Entwicklung einer eigenen Klasse (3)
Entwicklungsschritte
• OO-Analyse
• Identifikation von Objekten:
Zähler für Sekunden (modulo 60), Zähler für Stunden (modulo 24)
Idee: Eine Klasse soll Zählerobjekte modulo einer vorgebbaren Grenze nutzen können
• OO-Entwurf (-Design)
• Modellierung der Attribute und MethodenBeschreibung des Modells mit UML /Dokumentation
• Implementierung der Klasse
Testen der Klasse
Überlegungen zur Objektstruktur
Welche Merkmale sind charakteristisch für eine Uhr, also allen Uhrentypen gemeinsam?
Welche Funktionalitäten gehören zu den Basiseigenschaften einer Uhr? Bzw. Welche Dienste muss eine Uhr zur Verfügung stellen, um ihre Aufgabe zu erfüllen?
Lässt sich das Objekt Uhr noch zerlegen?
Beispiel:
Eine einfache Uhr mit Digitaler Anzeige soll mit Hilfe von geeigneten Objekten realisiert werden.
12 : 14 : 04
Modellierung des Zählers
12
Der Objekttyp Zähler
Welche Eigenschaften des Objekts Zähler sind für die Beschreibung in einem Programm von Interesse?
Ergebnisse der Analyse:
• Der Zählerstand: Er soll nur positive Werte (bzw. 0) annehmen können.
• Der Zähler arbeitet nach dem Prinzip: Weiterzählen, bis ein maximaler Wert erreicht ist, dann wieder bei Null beginnen.
• Der Zähler kann wieder in den Startzustand (Zählerstand 0) zurückversetzt werden.
• Der Zähler kann auf einen bestimmten (Anfangs-)Zählerstand gesetzt werden.
• Der Zählerstand kann ausgelesen werden.
Dokumentation:• Schnittstellen- und Verhaltensbeschreibung aller öffentlichen Methoden• Beschreibung des Modells mit UML
Entwicklungsschritte bisher weitgehend unabhängig von der Programmiersprache!
Implementation und Testprogramm
Testprogramm
13
• Test des Modulozähler-Objekts mit Hilfe eines Testprogramms
Fachklasse
(Datenmodell)
GUI- Klasse
(Anwendungsfenster)
Das Formular enthält Objekte zur Manipulation und Anzeige des Zählers.
• „Veröffentlichung„ der Klasse
• Entwicklung der Uhr mit Hilfe der ModuloZähler-Klasse
Zusammensetzen der Uhr
Aufgabe:Entwickle mit Hilfe der Zählerobjekte eine Uhr.Die Uhr soll dabei vorerst noch nicht selbst laufen und in die GUI eingebaut werden.
14
KlassendiagrammPrototyp
Die GUI verwaltet die Zählerobjekte(Hat-Beziehung)
Implementierung
15
procedure TGUI.zeitAnzeigen;
var
hs, ms, ss : string;
h,m,s : integer;
begin
h := stundenZaehler.getStand;
if h < 10 then
hs := '0' + IntToStr(h)
else
hs := IntToStr(h);
m := minutenZaehler.getStand;
if m < 10 then
ms := '0' + IntToStr(m)
else
ms := IntToStr(m);
Lanzeige.caption := hs+' : ' + ms;
end;
Erzeugung
procedure TGUI.FormCreate(Sender:
TObject);
begin
stundenZaehler :=
TModuloZaehler.create(23);
minutenZaehler :=
TModuloZaehler.create(59);
zeitAnzeigen;
end;
type
TGUI = class(TForm)
private
{ Private-Deklarationen }
stundenZaehler: TModuloZaehler;
minutenZaehler: TModuloZaehler;
public
procedure zeitAnzeigen;
{ Public-Deklarationen }
end;
Datenmodell Anzeigen der Zeit / Abfragen der Zählerstände
procedure TGUI.BTickClick(Sender: TObject);
begin
minutenZaehler.weiterZaehlen;
if minutenZaehler.getStand = 0 then
stundenZaehler.weiterZaehlen;
zeitAnzeigen;
end;
Die Uhr tickt
Nachteil: Steuerung Zähler in der GUI
Trennung von GUI und Datenmodell - MVC (2)
Analyse des entwickelten Programms zeigt:
• Uhr bildet noch keine Einheit (3 lose Bausteine).
• Steuerung der Zähler (Uhrwerk) erledig die GUI , was eigentlich Aufgabe der Uhr ist!
• Uhr abhängig vom Formular.
16
Verbesserung: Vollständige Entkopplung von GUI und Datenmodell (MVC)
Alternative Vorgehensweisen zur Erarbeitung des MVC-Entwurfsmusters:
Demonstration eines Programms mit vollständiger Trennung
– Experimente mit dem Programm
– Analyse dieses Programms
– Objekte mit Beziehungen zu anderen Objekten
siehe auch: Objektorientierte Software-Entwicklung - Teil 2
Entwicklung einer MVC- Uhr durch Erweiterung des entwickelten Programms
MVC-Modell einer Uhr
17
Darstellung
View
Steuerung
Control
Model
schreibt
liest
GUI
Realisierung der Entkopplung:• Das Model hat keinen Zugriff (keine Referenzen) auf GUI-Objekte!
Model in eigener Unit Model völlig unabhängig von der GUI.
• Die GUI hat Zugriff auf das Model (hat-Beziehung).
Diskussion:Vorteile/Nachteile
Modellierung der MVC-Uhr
18
Aufgabe:Entwickle mit Hilfe der Zählerobjekte eine Uhr.
Anforderungen:1. Die Uhr soll dabei vorerst noch nicht selbst laufen. 2. Die Uhr soll als eigenständiger Baustein, der unabhängig von GUI-Objekten ist, entwickelt werden.
Analyse• Die Uhr besitzt drei Zählerobjekte als
Stunden-, Minuten- und Sekundenzähler.• Stunden, Minuten und Sekunden können
gesetzt werden.• Stunden, Minuten und Sekunden können
ausgelesen werden.• Die Uhrzeit kann schrittweise erhöht
werden.
Kurzbeschreibung:• Das Uhrobjekt verwaltet die Zählerobjekte, d. h. es erzeugt
und vernichtet sie. • Gemäß dem Geheimnisprinzip werden die Zählerobjekte als
private bzw. protected deklariert, sind also dem Benutzerverborgen.
• Der Zugriff erfolgt indirekt mit Hilfe der Set- und Get-Methoden.
Klassendiagramm
Weitere Uhrenbeispiele
20
• Uhr-Beispiel wie im Buch "Barnes, Kölling: Java lernen mit BlueJ. Pearson Studium."
• Implementierungen mit Delphi :
– Objektorientierte Software-Entwicklung - Teil 1
– Katja Weishaupt: http://lernen.bildung.hessen.de/informatik/material/weishaupt.pdf
– K. Merkert (HSG-Kaiserlautern) http://www.hsg-kl.de/faecher/inf/material/se/swep/beispiele/uhren/uhr1/uhr1.php
• WeiterentwicklungenBeispiele: Selbstlaufende Uhr, Wecker, Schachuhr, Zeitzonenuhr,…
Entwicklung weiterer Klassen(6)
• Entwicklung objektorientierter Modelle (u. U. mit mehreren Klassen)
Beispiele:
Lottogenerator mit Tippscheinauswertung
Klasse "Bruch", die Kürzen und Erweitern als Dienste zur Verfügung stellt
Das Spiel "chuck a luck" mit Objekten für Würfel, Konto und Spielbrett
siehe auch: Objektorientierte Software-Entwicklung - Teil 1
…
Es empfiehlt sich, bei der Modellierung von Klassen darauf zu achten, dass diese auch in anderen
Zusammenhängen wiederverwendet werden können.
Abstraktion, Wiederverwendung
• Dokumentation
21
Zusammenfassung OOP
• OOP-Idee:
– Vorstrukturierung komplexer Systeme anhand natürlicher Objekte
– Jedes Objekt hat Fähigkeiten und Eigenschaften
– Verteilung von Aufgaben (Zuständigkeiten)
• Prinzipien:
– Objekt und Klasse
– Geheimnisprinzip
– Beziehung/Assoziation
– Vererbung
• Eine Klassen-Deklaration besteht aus Deklarationen von:
– Attributen für die verschiedenen Eigenschaftender Objekte
– Konstruktoren zur Erzeugung und Initialisierung der Objekte
– Methoden, d.h. Operationen (Algorithmen) auf Objekten
• UML-Klassendiagramm
– Zeigt die Klassen einer Anwendung und die Beziehungen zwischen diesen Klassen. Es liefert Informationen über den Aufbau der Anwendung.
• Entwurfsprinzip:
– Trennung von GUI und Modell (MVC)
22
Programmierprojekt (6)
Beispiel: Entwicklung interaktiver Spiele oder Simulationen
• Entwicklung eines interaktiven Roulette-Spiels (in Analogie zum Spiel "chuck a luck"); Anwendung des bisher Gelernten in einem etwas größeren Zusammenhang
• Ampelsteuerung
• Spielautomat (Slotmaschine)
• Memory
Vorgehensweise• Gemeinsam
Spezifikation der Anforderungen objektorientierte Analyse / und Design
• arbeitsteiligImplementierung der Klassen und Testen des Systems;
• begleitende Dokumentation des Systems siehe Dokumentationsgerüst (K. Merkert): http://www.hsg-kl.de/faecher/inf/material/se/swep/docugeruest.php
23
Vertiefung der bisher entwickelten Prinzipien
• MVC-Entwurfsmuster
• Phasen der OOPOOA OOD OOP - Zyklus
Links
Unterrichtmaterialien
• K. Merkert:http://hsg.region-kaiserslautern.de/faecher/inf/material/delphi/index.php
• R. Mechling:http://www.gk-informatik.de/
• K. Heidler:http://www.friedrich.fr.schule-bw.de/delphi/delphi.htm
• Hessischer Bildungsserver:http://lernen.bildung.hessen.de/informatik/
• S. Spolwig:http://oszhdl.be.schule.de/gymnasium/faecher/informatik/delphi/index.htm
• Martin Jakobs:http://www.martinjakobs.de/OOP/OOP.php
Werkzeuge• UMLed• Violet• BlueJ• JavaEditor
24
Zustandsbasierte ModellierungMVC
25
Zustandsbasierte Ablaufmodellierung
26
Problem:
Um Fehlbedienungen zu vermeiden müssen je nach Spielphase bestimmte Schaltflächen deaktiviert sein.
Beispiel: Spiels 17 und 4
Z0 Bereit - für ein neues Spiel
Z1 Spiel in Gang - Spieler würfelt
Modellierung des Spielverlaufs:
Spielzustände:
Spielsumme auf 0
Zahl anfordern
Spiel beenden
Modellierung des Zustandsautomaten
27
Steuerung durch Ereignisse:
Alter Zustand Auslösende Aktion Ausgelöste Aktion Neuer Zustand
Z0 BtNeuClick
Spielsumme auf 0
btNeu deaktivieren,
btZahl /Btaufhoeren aktivieren
Z1
Z1 btneueZahlClick
Spielsumme bestimmen
[Spielsumme < 21]
sonst
Spiel beenden
BtNeuClick aktivieren
btZahl /BtSpielbeenden aktivieren
Z1
Z0
Datentyp für Zustandsvariable:
TZustand = (z0, z1);
TGUI = class(TForm)
BtNeu: TButton;
BtZahl: TButton;
private
{ Private-Deklarationen}
Punkte : integer;
Ergebnis : string;
SpZustand : TZustand;
procedure neuerZustand;
public
{ Public-Deklarationen}
end;
Implementierung:
Implementierung
28
procedure TGUI.neuerZustand;
begin
case SpZustand of
z0 :
begin
SpZustand := z1;
BtNeu.Enabled := false;
BtZahl.Enabled := true;
BtSpielbeenden.Enabled := true;
end;
z1 :
begin
SpZustand := z0;
BtNeu.Enabled := true;
BtZahl.Enabled := false;
BtSpielbeenden.Enabled := false;
end;
end;
end;
Überführungsfunktion:
procedure TGUI.BtZahlClick();
var
Zufall : integer;
begin
//Eingabe
Zufall := random(6)+1;
//Verarbeitung
Punkte := Punkte + Zufall;
if Punkte >= 21 then
begin
if Punkte > 21 then
Ergebnis := 'Du hast leider verloren'
else
Ergebnis := 'Du hast gewonnen!!!';
neuerZustand;
end;
//Ausgabe
…
end;
Zustandswechsel auslösen
Simulation einer einzelnen Ampel(4)
29
Arbeitsschritte:
• Modellierung der einzelnen Phasen einer (deutschen) Ampel
Ziel:Simulation einer einzelnen Ampelmit klarer Trennung der Modellierung und Darstellung ( MVC-Konzept)
• Datenmodell:
Zustandsvariable, die 4 verschiedene Werte annehmen kann
Die Zustände werden zyklisch durchlaufen auf Tastendruck
Zustandsdiagramm
MVC-Architektur
30
GUI(graphical user interface)
Fachkonzept
Model
(Daten,Verarbeitung)
Controller
Steuerung
View
Ansicht
liest
schreibt
informiert
Die interne Datenverarbeitung ist von der Benutzeroberfläche (GUI) gänzlich abgekoppelt.
Die Modellklassen werden dazu in separaten Units gespeichert, die keine Beziehung zum Formular haben!
Das Modell kennt weder View noch Controller. Das bedeutet: In den Datenklassen werden keine View– oder Controllermethoden aufgerufen!
View und Controller kennen das Modell und lesen und schreiben die Daten.
View und Controller bilden bei Delphi das Formular.
Modellierung der Ampelsteuerung
31
Klassendiagramm
TZustand = (aus, rot, rotgelb, gruen, gelb);
Modellierung der Zustände
• Die Methode schalte ändert den Zustand zyklisch (Überführungsfunktion)• Die Methode wird von außen (Control) aufgerufen.• Die einzelnen Phasen sind noch gleich lang.
• Durch Änderung der Überführungsfunktion kann ein anderer Schaltzyklus erreicht werden, ohne dass an der GUI etwas geändert werden muss!
procedure TAmpelsteuerung.schalte;
begin //Überführungsfunktion
case Zustand of
aus : Zustand := rot;
rot : Zustand := rotgelb;
rotgelb : Zustand := gruen;
gruen : Zustand := gelb;
gelb : Zustand := rot;
end;
end;
Implementierung
Modellierung von View und Control
32
Viewmit Hilfe von Shapes
ControlSchaltfläche
Da die Steuerung keine Verbindung zur GUI hat, kann sie die Aktualisierung der Ansicht nicht auslösen, wenn sich der Ampelzustand ändert.Dies muss daher von GUI selbst initiiert werden!
Implementierung
33
procedure TGUI.BSchalterClick();
begin
Ampel.schalte;
aktualisiereAnsicht;
end;
procedure TGUI.aktualisiereAnsicht;
begin
case Ampel.GetZustand of
rot :
Panzeige.Caption := ‘Rot‘;
rotgelb:
Panzeige.Caption := ‘RotGelb‘;
gruen:
Panzeige.Caption := ‘Grün‘;
gelb:
Panzeige.Caption := ‘Gelb‘;
end;
end;
Die Ansicht fragt den Zustand der Ampel ab und aktualisiert sich, wenn sie dazu aufgefordert wird.
Dies kann auf unterschiedliche Weise geschehen:
• von der GUI bei jeder Aktivierung des Models
• permanent, timergesteuert (Polling)
• durch Ereignis, das vom Model ausgelöst wird
Weiterschalten der Ampel Aktualisierung der Ansicht
Vorteile des MVC-Entwurfs: • Die Darstellung kann sehr schnell geändert werden.• Ebenso die Steuerung, z. B. durch einen Timer
Links
• http://de.wikipedia.org/wiki/Lichtzeichenanlage
• Weitere Übungen und Vertiefungen z.B. Simulation zweier Ampeln an einer Baustelle wie inSpolwig
• Atze's Ampelsteuerungs-Nexus, Uni Hannoverhttp://www.kbs.uni-hannover.de/info1/info9899/aufgaben/Ampelsteuerung.html
• Bundeswettbewerb Informatik 2003,Aufgaben 2.Runde
• K. Merkert:http://www.hsg-kl.de/faecher/inf/material/se/swep/beispiele/ampelsteuerung/index.php
• http://www.ralphhenne.de/informatik/bluej/klasse11/03ZOM_Automat.pdf
34