Beruflich Dokumente
Kultur Dokumente
Software Engineering
zeigt Ihnen, wie Sie systematisch groe Software-Systeme im Team erstellen
gibt eine
Ubersicht uber das Gebiet des Software Engineering
ist Voraussetzung f ur das Software-Engineering-Praktikum
Klausur
Bachelor-, Lehramts- und Nachqualizierungs-Studenten m ussen durch eine Klausur am Ende
des Semesters einen Schein erwerben.
Termin
im Februar 2007
Anmeldung ist erforderlich.
Zugelassene Hilfsmittel: SE-Skript.
1
Software-Engineering-Praktikum
Ein Markenzeichen der Passauer Informatik!
Im Software-Engineering-Praktikum (SEP)
entwickeln Sie in 6er-Teams ein Software-Produkt
spielen Sie alle Phasen der Software-Entwicklung durch (Anforderungen, Entwurf, Imple-
mentierung, Test)
setzen Sie moderne Werkzeuge ein (Eclipse, Together, JUnit, SVN, ...)
Ziel
Entwicklung eines Systems im Team objektorientiert durch alle Phasen
Aufgaben
Internet-Tauschb orse, Navigationssystem, Handy-Programmierung...
Umfang
ca. 100 Klassen, ca. 10000 LOC Java-Code
Voraussetzungen
ndet im 5. Semester statt
Details + Anmeldung in einer Auftaktveranstaltung am Ende des 4. Semesters
2
Literatur
Grundlegend
Balzert: Lehrbuch der Software-Technik, Band 1 Software-Entwicklung. 2. Auage, Elsevier-
Verlag, 2001
Sommerville: Software Engineering. 7. Auage, Addison-Wesley, 2004.
Ghezzi, Jazayeri, Mandrioli: Fundamentals of Software Engineering. 2, Auage, Pearson
Education (Addison Wesley), 2002.
Gamma, Helm et.al: Design Patterns. Addison-Wesley, 1995.
Erg anzend
Balzert: Lehrbuch der Software-Technik, Band 2 Software-Management. Spektrum Aka-
demischer Verlag, 1997.
Beck: Extreme Programming Explained: Embrace Change. Addison-Wesley, 1999.
Fowler: Refactoring: Improving the Design of Existing Code. Addison-Wesley, 1999.
Industrielle Praxis
Humphrey: Managing Technical People. Addison-Wesley, 1997.
E. Yourdon: Decline & Fall of the American Programmer, Yourdon Press, 1992
Klassiker
G. M. Weinberg: The Psychology of Computer Programming, Van Nostrand, 1971
F. P. Brooks: The Mythical Man Month, Addison-Wesley, 1979.
3
Eine Auswahl der B ucher steht im Semesterapparat und in der Lehrbuchsammlung bereit.
4
Kapitel 1
Was ist Software Engineering?
Software Engineering ist
Multi-Personen-Konstruktion von Multi-Versionen-Software
(Parnas)
Software Engineering bietet
Management Theorie
Organisation Methoden
Werkzeuge Techniken
zur Konstruktion groer Programmsysteme.
Industrielle Softwareprojekte im Umfang von 500 Personenjahren sind keine Seltenheit!
Ziel: Einhalten von Qualit atsstandards
Vorbild: klassische Ingenieurdisziplinen wie Maschinenbau
Problem: Software ist unstetig:
Fehlt an einer Br ucke eine Schraube, so st urzt sie noch nicht ein
Stimmt in einem Programm 1 Bit nicht, kann das schon die Katastrophe bedeuten
Der Stand der Technik ist nicht der, dass Software ingenieurm aig entwickelt wird! (ob-
wohl es Programme gibt, die trotzdem funktionieren. . . )
5
Kapitel 2
Einige bekannte Software-Katastrophen
2.1 Ein schlimmes Beispiel
R ontgenger at verstrahlt 6 Menschen 3 Tote (1987)
Therac-25: medizinisches Bestrahlungsger at (R ontgen- und Elektronenstrahlen)
Nachfolger von Therac-6 und Therac-20
Therac-6 und Therac-20 benutzten Hardware-Sicherungen gegen zu hohe Strahlungsdosis
Therac-25 realisierte Sicherungen in Software
Wenn
1. der Operator die urspr unglichen Strahlungsart und Dosis eingab,
2. der Operator dann aber innerhalb von 8 Sekunden die Strahlungsart oder Dosis anderte,
wurde der Magnet nicht zur uckgesetzt falsche Strahlungsdosis
Fehlermeldungen traten sporadisch auf, waren aber unverst andlich
Da die Herstellerrma die Fehler zun achst nicht reproduzieren konnte, nahm sie sie lange nicht
ernst
Auerdem: Die Vorg anger Therac-6 und Therac-20 waren bew ahrt
6
2.2 Drei argerliche Beispiele
Intel Pentium: 1/824633702441.0 um 0.00005 zu gro (1994)
Intel ben otigte 1 Jahr, um den Fehler durch Zufallstesten (= Testen mit zuf alligen Werten) zu
nden
The value in the [algorithm] lookup table was numerically generated and downloaded into a
Programmable Lookup Array. A defect in the script resulted in a few entries in the lookup table
being omitted. When a division that required those entries was executed, an incorrect value was
retrieved.
1
Ariane 5 explodiert auf Jungfernug (1996)
Shortly after lift-off, the [untested] faulty software module attempted to compute a value based
on the horizontal velocity of the launcher. Because this value for Ariane 5 was signicantly larger
than the value expected for Ariane 4, an operand error occurred on both the backup and active
Inertial Reference System. The validity of this conversion was not checked because it was never
expected to happen.
The specication for error handling of the system indicated that the failure context should be
stored in EEPROM memory before shutting down the processor. After the operand error, the
Inertial Reference System set the failure context as specied, which was read by the onboard
computer. Based on these values, the onboard computer issued a command to the nozzle of the
solid boosters and the main engine. The command called for a full nozzle deection. . .
Geldregen am Geldautomat (1990)
A Norwegian Bank was embarrased yesterday after a cashpoint computer applied its own form
of fuzzy logic and handed out thousands of pounds no one had asked for. A long queue formed
at the the Oslo cashpoint after news spread that customers were receiving 10 times what they
requested.
2
1
Telles, Hsie: The Science of Debugging
2
ACM SIGSOFT Software Engineering Notes 15(3), 1990, S. 7
7
2.3 Drei lustige Beispiele
Wahlbeteiligung von 104% in Neu-Ulm (1994)
Bei der Wahl des Oberb urgermeisters in Neu-Ulm 1994 wurde zun achst eine Wahlbeteiligung
von 104% ermittelt. Sp ater mute man feststellen, da sich in die Auswertungssoftware ein my-
steri oser Faktor 2 eingeschlichen hatte.
3
Roboter begeht Selbstmord mit L osungsmittel (1988)
A Budd Company assembly robot has apparently commited suicide. The robot was programmed
to apply a complex bead of uid adhesive, but the robot ignored the glue, picked up a stful of
highly-active solvent, and shot itself in its electronics-packed chest.
4
F-16 zieht Fahrwerk auf Landebahn ein (1986)
One of the rst things the Air Force test pilots tried on an early F-16 was to tell the computer
to raise the landing gear while still standing on the runway. Guess what happened? Scratch one
F-16.
5
3
Partsch, Requirements Engineering Systematisch, S. 1
4
ACM SIGSOFT Software Engineering Notes 13(3), 1988, S. 3
5
ACM SIGSOFT Software Engineering Notes 11(5), 1986, S. 10
8
Kapitel 3
Der Software-Lebenszyklus
3.1 Code-and-Fix-Zyklus
geeignet f ur 1-Person-Projekte und Praktikumsaufgaben in den ersten Semestern (PdP/PI)
Ablauf:
1. Code schreiben und testen
2. Code
Entropie)
Wenn der Programmierer k undigt, ist alles vorbei
Heutige Projekte umfassen -zig Personenjahre
Wenn Entwickler und Anwender nicht identisch sind, gibt es oft Meinungsverschiedenhei-
ten uber den erwarteten/realisierten Funktionsumfang
Sogenannte Software-Krise (1968)
9
3.2 Prozemodelle
Die Software-Krise f uhrte zur Entwicklung strukturierter Prozemodelle.
Ein Prozemodell bietet eine Anleitung f ur den Entwickler, welche Aktivit aten als n achstes kom-
men.
Vorteil: Der Entwicklungsproze wird (aus betriebswirtschaftlicher Sicht) plan- und kontrollier-
bar.
Projektplanung
Kostenkontrolle
Abnahme von Zwischen- und Endprodukten
. . .
3.3 Wasserfallmodell
Machbarkeits-
Studie
Anforderungs-
Analyse
Entwurf
Codierung
+ Modultest
Integration
+ Systemtest
Installation
+ Wartung
10
Eigenschaften des Wasserfallmodells
Der Entwicklungsproze wird in Phasen zerlegt
Eine Phase mu abgeschlossen sein, bevor die n achste beginnt
Jede Phase produziert ein Dokument (auch ein Programm)
Die Phasen k onnen in Unterphasen unterteilt werden
3.3.1 Durchf uhrbarkeitsstudie
(Detaillierte Beschreibung in Kapitel 6)
Die Durchf uhrbarkeitsstudie soll Kosten und Ertrag der geplanten Entwicklung absch atzen
Dazu (grobe) Analyse des Problems mit L osungsvorschl agen, Alternativl osungen
F ur jeden L osungsvorschlag werden ben otigte Ressourcen, Entwicklungszeit und Kosten gesch atzt
Die Ergebnisse werden in einem Dokument festgehalten
Dieses Dokument ist h aug Grundlage eines Angebotes an einen potentiellen Kunden
Problem: oft hoher Zeitdruck und begrenzte Ressourcen
ungenaue Sch atzungen
Ist die Aufgabe exakt umrissen und das Umfeld bekannt, kann die Durchf uhrbarkeitsstudie auch
fehlen.
Ergebnis der Phase: Durchf uhrbarkeitsstudie
11
3.3.2 Anforderungsanalyse
(Detaillierte Beschreibung in Kapitel 7)
In der Anforderungsanalyse wird exakt festgelegt, was die Software leisten soll (aber nicht, wie
diese Leistungsmerkmale erreicht werden).
Alle relevanten Funktions- und Qualit atsmerkmale m ussen speziziert werden!
Diese Angaben werden im Pichtenheft (auch Lastenheft genannt) dokumentiert; das Pichten-
heft ist Bestandteil des Vertrages.
Eine Anforderungsdenition mu
verst andlich sein, und zwar f ur Auftraggeber und Auftragnehmer
pr azise sein, damit es hinterher nicht zu Streit um die Auslegung kommt
vollst andig und konsistent sein, da L ucken und Widerspr uche zu teuren R uckfragen f uhren
oder zu Katastrophen.
Am pr azisesten sind formale Spezikationen, die sich auch formal auf Vollst andigkeit und Wi-
derspruchsfreiheit uberpr ufen lassen. (Kapitel 16)
Nachteil allerdings: Kunde versteht formale Spezikationen nicht.
Deshalb h aug Verwendung von semiformalen Methoden, z.B. Entity-Relationship Diagramme,
Datenudiagramme
oder sogar Prosa (mit standardisiertem Vokabular/Glossar)
H aug ist die Benutzeranleitung (in vorl auger Form) bereits Bestandteil des Pichtenheftes.
(Kapitel 8)
Ergebnis der Phase: Pichtenheft
12
3.3.3 Entwurf
(Detaillierte Beschreibung in Kapitel 10 und 11)
Im Entwurf wird die Systemarchitektur festgelegt:
Welche Module (Objekte, Klassen) gibt es?
Welche Beziehungen bestehen zwischen ihnen?
H auges Vorgehen: Top-Down Entwurf
Zerlegung des Systems in Komponenten, Zerlegung der Komponenten in Unterkomponenten
usw.
Oft ist die Verwendung spezieller Architektur- oder Systembeschreibungssprachen sinnvoll.
Ergebnis der Phase: Entwurfsbeschreibung, die die Systemarchitektur festh alt.
3.3.4 Codierung und Modultest
(Detaillierte Beschreibung in Kapitel 17)
Eigentliche Implementierungs- und Testphase
Codierung und Testen war fr uher die einzige Phase.
Firmen verwenden oft Programmierrichtlinien, z.B. Programmlayout, Namenskonventionen, Kom-
mentierkonventionen
Das ist aber fragw urdig, denn veraltete Konventionen k onnen die Qualit at reduzieren:
Folgendes Beispiel wurde uns glaubw urdig berichtet: In einer Abteilung einer be-
kannten Automobilrma werden Variablennamen zentral vergeben und durchnume-
riert, nach dem Schema
Parkhaus-Story:
Der Fahrer bleibt an der geschlossenen Schranke stehen und fordert einen Park-
schein an.
Hat er diesen entnommen, offnet sich die Schranke
Der Fahrer passiert die Schranke, die dann wieder schliet.
Weitere Situationen (volles Parkhaus, Stromausfall. . . ) werden ebenfalls durch eige-
ne Stories beschrieben.
Zu jeder Story wird ein Testfall entworfen (der die Funktionalit at der Story abdeckt)
Die Entwicklung ist beendet, wenn alle Testf alle erf ullt sind
Pair Programming (Programmieren in Paaren) sorgt f ur st andiges Gegenlesen durch den
Partner (vergl. Abschnitt 17.3)
H auger, st andiger Rollenwechsel (Programme schreiben/lesen)
Teams werden stets neu zusammengestellt
Auch der Kunde kann so beteiligt sein
St andiges automatisches Testen sorgt daf ur, da Funktionalit at erhalten bleibt (vergl. Ab-
schnitt 16.2)
F ur jede neue Funktionalit at gibt es einen Testfall
Testf alle werden vor dem Programm geschrieben
Jeder kann jederzeit die Software umstrukturieren (refactoring(vergl. Kapitel 15)
Software mu entsprechend wandlungsf ahig sein
Testf alle m ussen weiterhin erf ullt werden
Code-Qualit at mu auf hohem Niveau bleiben
23
3.7.2 XP kennt keinen Entwurf
Das Extreme Programming kennt keine eigenen Entwurfsphasen:
Die Funktionalit at des Systems wird in Stories zusammengefat
Jede Story wird 1:1 in einen Testfall umgesetzt
Man nehme den einfachsten Entwurf, der die Testf alle besteht und implementiere ihn
Die Implementierung ist abgeschlossen, wenn alle Testf alle bestanden sind
Treten bei der Abnahme weitere Fragen auf, gibt es neue Stories und neue zu erf ullende
Testf alle
Der Kunde ist bei der gesamten Entwicklung dabei!
3.7.3 Einsatzbedingungen
Extreme Programming ist geeignet. . .
wenn die Anforderungen vage sind
wenn die Anforderungen sich schnell andern
wenn das Projekt klein bis mittelgro ist (< 1012 Programmierer)
Extreme Programming ist ungeeignet. . .
wenn es auf beweisbare Programmeigenschaften ankommt
wenn sp ate
Anderungen zu teuer werden
wenn h auges Testen zu teuer ist
wenn das Team zu gro oder nicht an einem Ort ist
24
3.7.4 Vor- und Nachteile
Positiv
Testf alle vor dem Codieren schreiben
Programmieren in Paaren
Umstritten
Kein Entwurf
Keine externe Dokumentation
Negativ
Erschwerte Wiederverwendung
Nur f ur kleine, hochqualizierte Teams geeignet
Erst wenig Erfahrung vorhanden
25
Eine alternative Sicht des Software-Lebenszyklus
26
Kapitel 4
Software-Qualit atsmerkmale
Wir unterscheiden
externe Qualit atsfaktoren: sichtbar f ur die Benutzer der Software
interne Qualit atsfaktoren: sichtbar f ur die Entwickler der Software
Qualit atsmerkmale m ussen validierbar sein.
27
4.1 Korrektheit
Korrekte Software erf ullt ihre Aufgabe entsprechend der Spezikation
Spezikation: funktionale Beschreibung der Anforderungen
was soll die Software tun, und was ist Voraussetzung daf ur
(aber nicht: wie tut sie es)
Korrektheit ist der wichtigste Qualit atsfaktor!
aber Korrektheit wird stets relativ zur Spezikation betrachtet:
ohne Spezikation keine korrekte Software
Die Spezikation mu deshalb hinreichend genau sein Miverst andnisse bei der Spezikation
sind die h augste und teuerste Fehlerquelle!
Verfahren zum
Uberpr ufen der Korrektheit:
Programmverikation (mathematisch)
Programmtest (empirisch)
Besser: (Teil)Korrektheitsgarantie per Konstruktion/Werkzeug:
konstruktive Verikation (Programmerstellung durch semiautomatische Transformation
der Spezikation in ausf uhrbares Programm)
statische Analysen (z.B. Typcheck: well typed programs cant go wrong)
Es gibt (fast) keine korrekten Softwaresysteme!
28
4.2 Zuverl assigkeit
Zuverl assige Software erf ullt ihre Aufgabe meistens
Im engeren Sinne ist Zuverl assigkeit die Wahrscheinlichkeit eines (gewichteten) Fehlers in einer
bestimmten Zeitspanne
Ahnliche Funktionen sollten auch auf ahnliche Weise ausgel ost werden!
Standardisierung kann Benutzerfreundlichkeit sehr erh ohen.
Beispiel: jeder kann sich schnell an ein anderes Auto gew ohnen, denn die Anordnung der Bedie-
nungselemente ist im wesentlichen dieselbe.
Aber steigen Sie mal von Word auf L
A
T
E
X um!
Groe Fortschritte durch Graphische Benutzerober achen (KDE, MacOS, Windows 95). Diese
bieten auch Style-Guides als Entwurfshilfen.
Psychologische Aspekte der Benutzerfreundlichkeit werden in der
Software-Ergonomie erforscht. Beispiel
personelle Trennung:
Jede/r sollte das machen, was er/sie am besten kann
In der Software-Entwicklung ist es selten,
da eine ganzheitliche Sicht der Dinge mehr bringt
43
5.3 Spezialfall: Modularit at
Modul = Software-Komponente mit wohldenierter Schnittstelle
Schnittstelle: Variablen und Operationen (samt Argument- und Ergebnistypen), die von auen
verwendet werden k onnen
Interne Realisierungsdetails (lokale Datenstrukturen und Algorithmen) sind nach auen unbe-
kannt!
Beispiel: Der Benutzer (Klient) eines Warteschlangen-Moduls braucht nicht zu wissen, ob die
Warteschlange als Feld oder verkettete Liste implementiert ist; er mu aber wissen, wie die
Operationen zum Anf ugen / Entfernen heien bzw. was diese f ur Argumente haben.
Vorbild: Klassische Ingenieurtechnik
Beispiel: Baugruppen (Platinen) in einem Fernseher.
Andere Baugruppen bedienen sich der Dienste einer Baugruppe nur uber eine Schnitt-
stelle, welche aus einigen Kabeln besteht; f ur jeden Anschlu sind die elektrischen
Eigenschaften genau speziziert. Die interne Schaltung einer Baugruppe ist nach au-
en uninteressant; Verbesserungen in einer Baugruppe betreffen andere Baugruppen
nicht, und im Fehlerfall kann eine Baugruppe einfach ausgetauscht werden.
Module sollten syntaktischen Einheiten der Sprache entsprechen
Schnittstellen sollen uber Mittel der Programmiersprache realisiert werden:
keine (implizite) Kommunikation uber globale Variablen,
keine (impliziten) Konventionen zum Funktionsaufruf
Grundprinzipien der Modularisierung:
Hohe Koh asion: Module sollten logisch zusammengeh orende Funktionen enthalten
Wenige Schnittstellen: Module sollten mit m oglichst wenig anderen Modulen kommunizieren
Schwache Kopplung: Module sollten so wenig Information wie m oglich austauschen
Geheimnisprinzip: Niemand darf modulinterne Daten abfragen oder manipulieren. Auf die
Dienste eines Moduls darf nur durch Aufruf von Schnittstellenfunktionen zugegriffen werden.
44
5.4 Abstraktion
Abstraktion: Ignorieren von irrelevanten Details;
Herausarbeiten des (f ur einen Zweck) Wesentlichen
Oft hat man Abstraktionshierarchien, wobei jede Schicht die ad aquate Beschreibung f ur einen
bestimmten Zweck ist:
Elektronen / Quantenmechanik
Transistoren / Festk orperphysik
Gatter / Boolesche Algebra
Maschinensprache / Rechnerorganisation
h ohere Sprache / Compilertheorie
Module und Komponenten / Software Engineering
Jede h ohere Schicht ignoriert Details der darunterliegenden Schicht
Klassischer Abstraktionsmechanismus in der Informatik: h ohere Programmiersprachen. Diese
verstecken die Details der Hardware.
Auch die Konstruktion eines Algorithmus ist eine Abstraktion: man abstrahiert von konkreten
Eingabedaten und sucht ein allgemeines Verfahren.
Software-Entwurf : Denition geeigneter Funktionsbausteine
Von der konkreten Realisierung der Bausteine wird abstrahiert
Abstraktion ist der K onigsweg zur Wiederverwendbarkeit:
Ersetze anwendungsspezische Teile durch formale Parameter
Instantiiere diese Parameter je nach Bedarf der Anwendung
Das Finden geeigneter Abstraktionen ist der Kern der Informatik
45
5.5 Spezialfall: Allgemeinheit
Every time you are asked to solve a problem, try to discover a more general problem
that may be hidden behind the problem at hand.
It may happen that the generalized problem is not more complexit may even be
simplerthan the original problem. Being more general, it is likely that the solution
to the more general problem has more potential for being reused.
It may even happen that the solution is provided by some off-the-shelf package. Also,
it may happen that by generalizing a problem you end up designing a module that
is invoked at more than one point of the application, rather than having several
specialized solutions. (Ghezzi)
Beispiele:
Allgemein verwendbares Sortierprogramm
Tabellenkalkulation
Datenbanksystem
Grak-Bibliothek
Textprozessoren (z.B. AWK)
statt
Quicksort f ur Arrays fester Gr oe
Selbstgebastelter Taschenrechner
Handimplementierte Rot/Schwarz-B aume
Direktes Ansprechen der Grakkarte
Selbstrealisierter Knuth-Morris-Pratt-Algorithmus zur Textsuche
Allgemein verwendbare Software verkauft sich besser!
46
5.6 Evolutionsf ahigkeit (
from scratch.
Heute: Anpassen existierender Komponenten; Evolution bestehender Systeme
47
5.7 Spezialfall: Inkrementalit at
Inkrementalit at = Vorgehen in kleinen Schritten
Inkrementalit at im Software Engineering: ein Produkt wird als Sequenz von Approximationen
realisiert (
7
1
Wenig Kopplung
2
Schnittstellen sind meist inefzienter als direkter Zugriff
3
H auger und fr uher Feedback durch Anwender
4
Strenge und Formalit at erfordern kurzfristig h oheren Aufwand (bringen aber mittelfristig Gewinn, s. Wartbar-
keit)
5
Fr uhzeitige Eink unfte durch fr uhe Auslieferung unvollst andiger Versionen
6
Sicherheitskritische Software wird auf ein bestimmtes Umfeld hin veriziert
7
Viele Revisionen instabile Software!
49
Kapitel 6
Pr ufung der Durchf uhrbarkeit
Bevor mit der eigentlichen Software-Entwicklung begonnen werden kann, mu in der Durchf uhr-
barkeitsstudie gepr uft werden, ob
die fachliche Durchf uhrbarkeit,
die okonomische Durchf uhrbarkeit und
die personelle Durchf uhrbarkeit
gegeben sind.
Ziel ist, zu pr ufen, ob ein Produkt entwickelt werden soll.
50
6.1 Die Durchf uhrbarkeitsstudie
Zur Pr ufung der Durchf uhrbarkeit geh ort:
Ausw ahlen des Produkts
Trendstudien
Marktanalysen
Forschungsergebnisse
Kundenanfragen
Vorentwicklungen
Voruntersuchung des Produkts
Ist-Analyse (etwa gegenw artiges Produkt)
Festlegen der Hauptanforderungen:
Hauptfunktionen, -daten, -leistungen
Aspekte der Benutzerschnittstelle
Wichtigste Qualit atsmerkmale
Durchf uhrbarkeitsuntersuchung
Fachliche Durchf uhrbarkeit (Softwaretechnische Realisierbarkeit,
Verf ugbarkeit geeigneter Hardware)
Alternative L osungsvorschl age (etwa Anpassung
von Standardsoftware vs. Neuerstellung)
Personelle Durchf uhrbarkeit (Aufwandsabsch atzung,
Lage am Arbeitsmarkt)
Pr ufen der Risiken
Pr ufung der okonomischen Durchf uhrbarkeit
Aufwands- und Terminabsch atzung
Wirtschaftlichkeitsrechnung
Die Durchf uhrbarkeitsstudie besteht aus
1. Lastenheft,
2. Projektkalkulation und
3. Projektplan.
51
6.2 Das Lastenheft
Das Lastenheft (auch grobes Pichtenheft) f uhrt alle fachlichen Anforderungen auf, die die fer-
tige Software aus Sicht des Auftraggebers erf ullen mu.
Es ist das erste Dokument, das die Anforderungen an ein neues Produkt grob beschreibt.
Typischer Aufbau des Lastenhefts
1
1 Zielbestimmung
Welche Ziele sollen durch den Einsatz der Software erreicht werden?
2 Produkteinsatz
F ur welche Anwendungsbereiche und Zielgruppen ist die Software vorgesehen?
3 Produktfunktionen
Was sind die Hauptfunktionen des Produktes aus Sicht des Auftraggebers?
Die Hauptfunktionen (Kernfunktionen, keine Details!) werden typischerweise einzeln ge-
kennzeichnet (etwa /LF10/, /LF20/, . . . ), um sich in sp ateren Dokumenten auf sie beziehen
zu k onnen.
4 Produktdaten
Was sind die (permanent gespeicherten) Hauptdaten des Produkts?
Hier ebenfalls Kennzeichnung (mit /LD10/, /LD20/, . . . )
5 Produktleistungen
Werden f ur bestimmte Funktionen besondere Anspr uche in Bezug auf Zeit, Datenumfang
oder Genauigkeit gestellt? Welche?
Hier ebenfalls Kennzeichnung (mit /LL10/, /LL20/, . . . )
6 Qualit atsanforderungen
Aufz ahlung der wichtigsten Qualit atsanforderungen wie Zuverl assigkeit, Robustheit, Be-
nutzerfreundlichkeit, Efzienz . . .
7 Erg anzungen
Gibt es auergew ohnliche Anforderungen, die nicht durch obige Punkte abgedeckt sind?
Welche?
Typischer Umfang: nur wenige Seiten
1
aus Balzert, Lehrbuch der Software-Technik
52
6.3 Projektkalkulation
Software ist teuer. Noch teurer aber werden (zumindest f ur den Hersteller) falsche Preisvorstel-
lungen.
Zur Kalkulation der anfallenden Kosten gibt es viele Modelle:
Analogiemethode
Vergleich der zu sch atzenden Entwicklung mit bereits abgeschlossenen Entwicklungen
anhand von
Ahnlichkeitskriterien.
Nachteil: Expertenwissen oft nicht nachvollziehbar
Relationsmethode
Analogiemethode mit Faktorenliste (etwa Faktor Programmiersprache: PASCAL = 100,
COBOL = 120, ASSEMBLER = 140)
Bei Wechsel innerhalb eines Faktors kann so der Aufwand neu bestimmt werden
Multiplikatormethode
Aufwandssch atzung f ur einzelne Teilsysteme der Software. Bestimmte Teilsysteme sind
(erfahrungsgem a) teurer als andere (etwa: Datenverwaltung 1,0; Algorithmen 2,0)
Gesamtaufwand ergibt sich als Summe des Aufwands f ur die Teilsysteme.
Gewichtungsmethode
Bestimmung zahlreicher Faktoren objektiv wie
Erfahrung des Personals und Verkn upfung aller Faktoren gem a mathe-
matischer Formel
Bekannteste Vertreter: Constructive Cost Model (COCOMO), Function-Point-Methode
(derzeit einzige empfehlenswerte)
Iterative Anwendung: Einufaktoren m ussen regelm aig angepat werden
Prozentsatzmethode
Aus abgeschlossenen Entwicklungen wird ermittelt, wie sich der Aufwand auf die einzel-
nen Phasen verteilt hat (etwa: Spezikation 20%). Bei neuen Projekten kann dann aus
der tats achlichen Dauer der abgeschlossenen Phasen der Aufwand f ur die Restphasen
gesch atzt werden.
Wird gew ohnlich mit einer der obigen Methoden kombiniert
Parkinsons Gesetz
Die Arbeit ist beendet, wenn alle Vorr ate aufgebraucht sind.
53
6.3.1 Function-Point-Methode
Bei der Function-Point-Methode wird der Aufwand f ur ein neues Projekt aus den Produktanfor-
derungen berechnet. Dies erfolgt in sieben Schritten, bei denen ein spezielles Berechnungsfor-
mular ausgef ullt wird:
54
1. Schritt: Jede Produktanforderung wird eine der folgenden f unf Kategorien zugeordnet:
Eingabedaten
Abfragen
Ausgaben
Datenbest ande
Referenzdaten
2. Schritt: Kategorisierung der Anforderungen in Klassen
einfach
mittel
komplex
Dazu werden Tabellen, Beispiele, Richtlinien verwendet.
3. Schritt: Mit diesen Daten wird der erste Teil des Bewertungsbogens ausgef ullt und die Sum-
me berechnet. Diese Summe bildet die unbewerteten Gesamtpunkte.
4. Schritt: Weitere sieben Einussfaktoren werden gesch atzt und im Formular eingetragen. F ur
die Sch atzungen werden in der Regel rmeninterne Richtlinien verwendet. Aus diesen
Einussfaktoren wird die Summe gebildet.
5. Schritt: Im f unften Schritt wird aus den Einussfaktoren ein Faktor berechnet und mit den
unbewerteten Gesamtpunkten multipliziert. Das Ergebnis sind die Function Points.
6. Schritt: Anschliessend werden in einer Aufwandskurve, die eine Abbildung von Function
Points auf Mitarbeiter-Monate (MM) darstellt, die ben otigten MM f ur das Projekt abge-
lesen. Diese Kurve ist rmenspezisch und ergibt sich aus fr uheren Projekten, indem die
f ur die Projekte berechneten Function Points und die tats achlich ben otigten Mitarbeiter-
Monate eingetragen werden.
7. Schritt: Nach Beendigung des Projekts wird die Aufwandskurve mit den Werten des Projekts
f ur Function Points und ben otigte Mitarbeiter-Monate aktualisiert.
55
s
t
T
u
t
o
r
i
a
l
(
2
P
M
)
T
3
:
I
n
h
a
l
t
T
u
t
o
r
i
a
l
(
3
P
M
)
T
4
:
B
e
i
s
p
i
e
l
e
T
u
t
o
r
i
a
l
(
2
P
M
)
T
6
:
J
a
v
a
-
A
u
f
g
a
b
e
n
T
u
t
o
r
i
a
l
(
2
P
M
)
P
3
:
J
a
v
a
-
A
u
f
g
a
b
e
n
P
r
a
k
t
o
m
a
t
(
2
P
M
)
E
1
:
E
n
t
w
u
r
f
E
l
.
T
u
t
o
r
e
n
(
1
P
M
)
E
6
:
"
F
o
r
m
a
t
i
e
r
u
n
g
"
(
1
P
M
)
E
8
:
"
D
o
k
u
m
e
n
t
a
t
i
o
n
"
(
1
P
M
)
E
7
:
"
K
o
m
p
l
e
x
i
t
t
"
(
2
P
M
)
E
5
:
"
B
e
z
e
i
c
h
n
e
r
"
(
1
P
M
)
E
2
:
E
i
n
r
i
c
h
t
e
n
J
a
v
a
-
P
a
r
s
e
r
(
1
P
M
)
P
1
:
J
a
v
a
-
A
n
p
a
s
s
u
n
g
P
r
a
k
t
o
m
a
t
(
1
P
M
)
P
2
:
I
n
t
e
g
r
a
t
i
o
n
E
l
.
T
u
t
o
r
e
n
+
P
r
a
k
t
o
m
a
t
(
2
P
M
)
T
5
:
I
n
t
e
g
r
a
t
i
o
n
E
l
.
T
u
t
o
r
e
n
+
B
e
i
s
p
i
e
l
e
(
2
P
M
)
P
r
o
j
e
k
t
b
e
g
i
n
n
+
1
M
o
n
a
t
+
3
M
o
n
a
t
e
+
1
0
M
o
n
a
t
e
+
1
2
M
o
n
a
t
e
+
1
4
M
o
n
a
t
e
W
r
z
b
u
r
g
P
a
s
s
a
u
K
1
:
P
r
o
j
e
k
t
-
K
o
o
r
d
i
n
a
t
i
o
n
(
2
P
M
)
T
7
:
I
n
t
e
g
r
a
t
i
o
n
T
u
t
o
r
i
a
l
+
P
r
a
k
t
o
m
a
t
(
1
P
M
)
E
9
:
"
T
e
s
t
"
(
2
P
M
)
K
2
:
K
o
o
r
d
i
n
a
t
i
o
n
(
2
P
M
)
E
3
:
"
M
u
s
t
e
r
l
s
u
n
g
"
(
2
P
M
)
E
4
:
"
S
c
h
n
i
t
t
s
t
e
l
l
e
"
(
2
P
M
)
62
6.5 Checkliste: Durchf uhrbarkeitsstudie
F ur Praktika ist die Durchf uhrbarkeit ex cathedra gegeben, so da eine eigene Studie in der Regel
entf allt.
Dennoch sollten die folgenden Punkte, wenn schon nicht als Teil der Durchf uhrbarkeitsstudie, in
den nachfolgenden Dokumenten behandelt werden.
Ist ein Zeitplan enthalten?
Der Zeitplan mu die
Uberg ange zwischen den einzelnen Phasen mit Datum enthalten.
Sind Autoren und Phasenverantwortlichen aufgef uhrt?
F ur jede Phase ist ein Gruppenmitglied zu benennen, das f ur die Termineinhaltung und die
geforderten Dokumente verantwortlich zeichnet.
Sind Risiken hinreichend abgesch atzt?
Was passiert, wenn einzelne Gruppenmitglieder ausfallen oder unzureichende Arbeit lie-
fern?
63
6.6 Checkliste: Allgemeine Anforderungen
an Dokumente
Dokumente im Rahmen des Praktikums werden anhand der folgenden Anforderungen beurteilt.
6.6.1 Allgemeines
Fehlerfrei schreiben
Rechtschreibfehler werden durch handels ubliche Korrekturprogramme erkannt, grammatikali-
sche Fehler durch lautes Vorlesen.
Wer sich nicht sicher ist, soll einen Korrektor nden.
Verbliebene Fehler sind Zeichen f ur mangelnde Sorgfalt und zeigen so Geringsch atzung f ur den
Leser.
Auch Praktikums-Betreuer haben Anspruch auf Wertsch atzung.
Gliederung
Die Gliederung sollte ausgewogen sein; d.h. die L ange der einzelnen Abschnitte und die Anzahl
der Unterpunkte sollten nicht grob voneinander abweichen.
Die Gliederungstiefe soll 3 nicht uberschreiten. Unsch on:
1.1 Motivation
1.1.2 Aufgabenstellung
1.1.2.1 Einf uhrung
1.1.2.1.1 Denitionen
1.1.2.1.1.1 Allgemeines
Die Abschnitt uberschriften m ussen zum Inhalt passen und umgekehrt.
Typographie
Das Sein als Schein, Frankfurter Rundschau 1998-15-10, S. 6, zur Frage, ob Studenten f ur
Scheine oder f ur die Wissenschaft studieren
5
E. A. Rauter, Vom Umgang mit W ortern, M unchen 1980
6
Ludwig-Reimers-Schema, zitiert nach: Wolf Schneider, Deutsch f ur Pros
68
Hauptfeind: Der Schachtelsatz
Schachtels atze vermeiden. In der Karikatur:
Denken Sie, wie sch on der Krieger, der die Botschaft, die den Sieg, den die Athener
bei Marathon, obwohl sie in der Minderheit waren, nach Athen, das in groer Sorge,
ob es die Perser nicht zerst oren w urden, schwebte, erfochten hatten, verk undete,
brachte, starb!
Im wirklichen Leben:
Als Vorbedingung der Funktion gilt, da alle ubergebenen Argumente, wobei zu
ber ucksichtigen ist, da das letzte Argument, der Pr ufmodus, optional ist mit einer
Vorgabe von false, im angegebenen Wertebereich liegen m ussen.
Besser geht das in drei kurzen S atzen:
Als Vorbedingung m ussen alle Argumente im angegebenen Wertebereich liegen. Der
Pr ufmodus kann weggelassen werden. Ist dies der Fall, so gilt der Pr ufmodus als
abgeschaltet.
Noch besser: Satzkn auel durch Tabellen und Aufz ahlungen gliedern. Dies ist ein zentrales Prinzip
f ur technische Dokumentationen.
Hier:
Vorbedingungen:
1. Alle Argumente m ussen im angegebenen Wertebereich liegen.
2. Der Pr ufmodus kann weggelassen werden. Ist dies der Fall, so gilt der Pr ufmo-
dus als abgeschaltet.
Mark Twain meint:
Ich w urde jeden Menschen, ob hoch oder niedrig, ersuchen, seine Geschichte klar
und einfach zu entwickeln. Sonst soll er sich auf sein Redekn auel setzen und gef alligst
Ruhe halten. Verst oe gegen dieses Gesetz w urde ich mit dem Tode ahnen.
7
7
Mark Twain, Die schreckliche deutsche Sprache, S. 51, Manuscriptum 1998
69
Redundanz vermeiden
In journalistischen Texten und im gesprochenen Wort (wie in Vorlesungen) gilt: Je komplizierter
das Thema, um so mehr Redundanz.
Erst sage ich den Leuten, was ich ihnen sagen werde. Dann sage ich es ihnen. Dann
sage ich ihnen, was ich ihnen gerade gesagt habe.
Erfolgsrezept eines amerikanischen Predigers
In technischen Texten aber schadet Redundanz der Pr azision!
Grundsatz: Werden Dinge aus verschiedenen Blickwinkeln betrachtet, sorgt die Vielfalt f ur gr oe-
re Pr azision.
Ansonsten aber: Alles weglassen, was vorausgesetzt werden kann oder sich aus dem Gesagten
ergibt.
Statt:
Die Klasse A ist eine Unterklasse von B, d.h. sie erbt alle Attribute.
heit es:
A ist eine Unterklasse von B.
Nicht aus allgemein zug anglichen Werken abschreiben!
Der Entwurf erf ullt alle Grundprinzipien des Software Engineering, n amlich: 1)
Strenge und Formalit at, 2) Separation der Interessen . . . .
Stattdessen zitieren:
Der Entwurf erf ullt alle Grundprinzipien des Software Engineering (Ghezzi, 1991).
Allgemeinpl atze sind nur im ersten Satz der ersten Seite zul assig:
Schachspielen ist schwer. Unser Schachprogramm macht es Ihnen leicht. . .
70
F ullw orter vermeiden
Streichen von F ullw ortern hilft, S atze zu verk urzen:
auch doch eben
geradezu reichlich eigentlich
ausgerechnet vielleicht interessant
weitgehend ein St uck weit im allgemeinen
insbesondere irgendwie in diesem Zusammenhang
sowohl als auch sozusagen relativ
praktisch quasi sicherlich
unzweifelhaft voll und ganz mehr oder weniger . . .
Ein Beispiel:
8
Ich mu meine Bezugssysteme thematisieren und da diese dann auch und gerade
gesellschaftliche (und eben auch soziologische) sein k onnen, m ussen und werden, ist
praktisch unabwendbar.
Umpf! Sollte dies etwa heien:
Wir m ussen mal dar uber reden.
Vergleiche hierzu:
9
Die Kunst, geisteswissenschaftlich unwiderlegbar zu werden, besteht darin, so lange
zu abstrahieren, bis der endlich gefundene Begriff alle konkreten Angriffs achen
verloren hat damit freilich auch jede Farbe, alle Kraft, jeden praktischen Sinn.
Unser Ziel: Pr azision! K urze! Und wenn nach dem Streichen von F ullw ortern irgendwie weitge-
hend Banalit aten ubrig bleiben den Satz als Ganzes streichen, auch und gerade wenn es relativ
weh tut.
8
Schl uter, a.a.O.
9
Rudolf Walter Leonhart, Das Deutsch des deutschen Fernsehens, Die Zeit, 1980-12-05
71
6.6.4 Wie wendet man diese Regeln an?
Wolf Schneider, Leiter der Journalistenschule von Gruner + Jahr, h alt es so:
10
Laut lesen.
Dabei oder danach:
die meisten F ullw orter und m oglichst viele Adjektive streichen
bei fahrl assigen Wiederholungen andere W orter einsetzen
rote Schlangenlinien an Stellen des Mivergn ugens machen
Den logischen Ablauf pr ufen.
Den dramaturgischen Aufbau pr ufen.
Alle Stellen uberarbeiten, die eine Schlangenlinie bekommen haben.
Die Passagen uberarbeiten, die den Gegenlesern mifallen haben.
Noch mal laut lesen.
10
Wolf Schneider, Deutsch f ur Pros, Stern-Buch, 1984
72
Kapitel 7
Software-Denition: Pichtenheft
7.1 Die Produkt-Denition
Die Anforderungen an eine neue Software sind von ihrer Natur her vage, verschwommen, unzu-
sammenh angend, unvollst andig und widerspr uchlich.
Ziel der Software-Spezikation ist es, aus diesen Anforderungen eine m oglichst vollst andige
konsistente und eindeutige Produkt-Denition zu erstellen, die Grundlage f ur das zu erstellende
Produkt ist.
Zur Produkt-Denition geh oren vier Teile:
Das Pichtenheft oder Anforderungsdokument.
Legt (verbal) die Anforderungen an die fertige Software fest.
Das Produkt-Modell.
Speziziert den Aufbau und wichtige Eigenschaften des Produkts. Dies geht mit
semi-formalen Denitionsverfahren, die imZusammenspiel mit demBenutzer erstellt
werden, oder mit
formalen Spezikationsverfahren, die als pr azise Grundlage f ur die Implementierung
dienen.
Die Beschreibung der Benutzungsober ache.
Wird typischerweise aus den Erfahrungen mit Prototypen gewonnen.
Das Benutzerhandbuch.
Wird gew ohnlich weit vor der eigentlichen Implementierung erstellt.
73
7.2 Das Pichtenheft
Das Pichtenheft legt (verbal) die Anforderungen an die fertige Software fest.
7.2.1 Typischer Aufbau
(nach Balzert, Lehrbuch der Software-Technik)
1 Zielbestimmung
Mukriterien
Welche Leistungen sind f ur das Produkt unabdingbar?
Wunschkriterien
Welche Leistungen sind erstrebenswert?
Abgrenzungskriterien
Welche Ziele sollen bewut nicht erreicht werden?
2 Produkt-Einsatz
Anwendungsbereiche
Zu welchem Zweck wird das Produkt eingesetzt?
Zielgruppen
Von wem soll das Produkt eingesetzt werden? Welches Qualikationsniveau des Be-
nutzers wird vorausgesetzt?
Betriebsbedingungen
Wie ist die physikalische Umgebung? Die Betriebszeit? Aufsicht?
3 Produkt-Umgebung
Software
Welche Software-Systeme sollen auf der Zielmaschine zur Verf ugung stehen?
Hardware
Welche Hardware-Komponenten werden ben otigt?
Orgware
Welche organisatorischen Bedingungen m ussen erf ullt sein?
4 Produkt-Funktionen
Funktion 1
. . .
Funktion 2 usw.
Was leistet das Produkt aus Benutzersicht?
Wichtig: Nicht das Wie, sondern das Was wird hier deniert.
74
Jede Einzelanforderung mu gesondert gekennzeichnet sein (etwa als /F10/, /F20/,
usw.)
5 Produkt-Daten
Daten 1
. . .
Daten 2 usw.
Was speichert das Produkt (langfristig) aus Benutzersicht?
Auch hier sollten die zu speichernden Daten gesondert gekennzeichnet sein (etwa als
/D10/, /D20/, usw.)
Hier werden h aug auch bereits Aussagen uber das Datenformat getroffen.
6 Produkt-Leistungen
Welche zeit- und umfangsbezogenen Anforderungen gibt es?
Kennzeichnung als /L10/, /L20/, usw.
7 Benutzungsober ache
Was sind die grundlegenden Anforderungen an die Benutzerober ache?
Umfat Bildschirmlayout, Drucklayout, Tastaturbelegung, Dialogstruktur, usw.
8 Qualit ats-Zielbestimmung
Verweis auf g angige Normen und Standards
9 Globale Testszenarien und Testf alle
Testfall 1
. . .
Testfall 2 usw.
Was sind typische Szenarien, die das Produkt erf ullen mu?
Ein Szenario sollte eine Schritt f ur Schritt-Anleitung f ur den Tester sein:
/T10/ W ahlen Sie das Objekt 1 aus /F10/.
/T20/ L oschen Sie es /F25/ . . .
Die Testf alle (gekennzeichnet durch /T10/, /T20/, usw.) sollen die Anforderungen
vollst andig abdecken.
Testszenarien sind typischerweise Grundlage f ur den Abnahmetest.
10 Entwicklungs-Umgebung
Software
75
Hardware
Orgware
Welche Umgebung wird f ur die Entwicklung ben otigt?
11 Erg anzungen
Hierunter fallen
Spezielle, nicht abgedeckte Anforderungen
Installationsbedingungen
Zu ber ucksichtigende Normen, Lizenzen, Patente
Glossar
Denition aller wichtigen Begriffe zur Sicherstellung einer einheitlichen Terminologie
Glossar soll nicht Allgemeinpl atze denieren (etwa
CPU,
unsigned-integer = digit
+
unsigned-number = unsigned-integer(.digit
+
)
?
(E(+ [ -)
?
unsigned-integer)
?
unsigned-constant = constant-identier [ unsigned-number [
NIL [ character
+
constant =
_
(+ [ -)
?
(constant-identier [ unsigned-number)
_
[
character
+
Aus solchen Beschreibungen lassen sich automatisch endliche Automaten konstruieren, die Be-
standteile einer Eingabe erkennen und verarbeiten (siehe auch Abschnitt 7.6.1).
87
7.6 Zustandsorientierte Modellierung
7.6.1 Endliche Automaten
Ein endlicher Automat beschreibt ein System als eine (endliche) Menge von Zust anden.
Die
Uberg ange zwischen den einzelnen Zust anden sind an bestimmte Bedingungen gekn upft.
Ist die Bedingung f ur den
Ubergang erf ullt, geht das System in einen neuen Zustand uber.
Beispiel: Stellen einer Digitaluhr
6
6
aus Balzert, Lehrbuch der Software-Technik
88
Beispiel: Mikrowellenofen
7
Zust ande bzw.
Uberg ange entsprechen realen Schaltern/Sensoren/Lampen
Zust ande und
Uberg ange m ussen separat erl autert werden:
7
aus Sommerville, Software Engineering
89
Beispiel: Grobstruktur einer Prozekontrolle in einer chemischen Fabrik
8
Dieses Beispiel illustriert, wie Automaten verfeinert werden k onnen, indem ein Zustand durch
einen ganzen Teilautomaten ersetzt wird.
Nat urlich m ussen die urspr unglichen
Uberg ange aus/in einen verfeinerten Zustand sich im neuen
Teilautomaten wiedernden! Diese Bedingung ist im folgenden Beispiel verletzt.
8
aus Ghezzi, Fundamentals of Software Engineering
90
7.6.2 Statecharts
Erlauben die Beschreibung nebenl auger Zust ande
91
7.6.3 Petri-Netze
Beschreiben parallele und asynchrone Systeme
Petri-Netze
sind gerichtete Graphen, deren Knoten entweder Stellen oder Transitionen sind
Stellen
dienen als Aufnahmebeh alter f ur Marken
Transitionen
sind die
Ubergabewege f ur Marken
Marken
beschreiben durch ihre Anzahl und Position den Zustand eines Petri-Netzes
Der Bewegungsablauf von Marken im Netz wird durch die Schaltregel festgelegt:
Eine Transition t kann schalten, wenn jede Eingabestelle von t wenigstens eine Marke
enth alt
Schaltet eine Transition, wird aus jeder Eingabestelle eine Marke entfernt und jeder Aus-
gabestelle eine Marke hinzugef ugt
92
Bedingungs/Ereignis-Netz
Einfachste Form von Petri-Netzen: Jede Stelle kann genau eine oder keine Marke enthalten
Weitere Schaltregel:
Eine Transition t kann schalten, wenn jede Eingabestelle von t eine Marke enth alt und jede
Ausgabestelle von t leer ist
Beispiel: Best ucken von Leiterplatten durch zwei Roboter
9
9
aus Balzert, Lehrbuch der Software-Technik
93
94
Welche der beiden Transitionen feuert (und welcher Roboter die Leiterplatte ergreift), ist nicht
deterministisch!
Weitere Petri-Netze:
Stellen/Transitions-Netze
Jeder Kante ist eine maximale Kapazit at zugeordnet; jede Transition mu entsprechend
der Kapazit at Marken hinzuf ugen und entfernen
Pr adikat/Transitions-Netze
Marken sind unterschiedlich gef arbt; Pr adikate an den Transitionen geben an, unter wel-
chen Bedingunen die Transitionen schalten d urfen
Hierarchische Petri-Netze
zur Strukturierung groer Systeme
Zeitbehaftete Petri-Netze
mit
Alarm, so wird die Weiche rot blinkend gezeichnet. Die Abbildung richtet sich
nach der Aufl osung des Bildschirms.
Was ist der Unterschied zwischen
Ausleuchtung,
Darstellen,
Abbilden,
Zeichnen?
Mit zwei Glossar-Eintr agen
Ausleuchtung und
Alarm, so wird die Weiche rot blinkend dargestellt. Die Darstellung rich-
tet sich nach der Aufl osung des Bildschirms.
Das Glossar sollte nach Stichworten alphabetisch sortiert sein.
Gibt es einen Index?
Bei umfangreichen Dokumenten ist ein Index (am Ende des Dokuments) hilfreich.
101
Kapitel 8
Gestaltung von Benutzer-Handb uchern
Das Benutzer-Handbuch ist in der Regel der erste Kontakt eines Benutzers mit einem neuen
Software-System.
Das Handbuch ist sozusagen die Visitenkarte des Systems; entsprechend sorgf altig sollte es ge-
staltet sein.
8.1 Aufgabe
Das Benutzer-Handbuch soll die Handhabung und das Verhalten des Produkts m oglichst vollst andig
und fehlerfrei beschreiben.
Es mu m oglich sein, das Produkt nur anhand des Handbuchs zu bedienen.
8.2 Benutzer-Kategorien
Anordnung und Aufbau eines Handbuchs werden im wesentlichen durch die Adressaten be-
stimmt. Man unterscheidet drei Kategorien:
Anf anger haben keine oder wenig Erfahrungen mit Computersystemen im allgemeinen
und dem Produkt im speziellen.
Experten haben viel Erfahrungen mit Computersystemen im allgemeinen, aber wenig Er-
fahrungen mit dem speziellen Produkt.
Fortgeschrittene liegen irgendwo zwischen Anf angern und Experten; sie haben vielleicht
schon ahnliche Produkte benutzt.
102
8.3 Handbuchtypen
F ur jede Benutzer-Kategorie gibt es eigene Handbuch-Typen:
Trainings-Handbuch (Tutorial)
Referenz-Handbuch
Referenzkarte
Benutzer-Leitfaden (user guide)
8.3.1 Trainings-Handbuch (Tutorial)
F ur Anf anger am besten geeignet.
Ein Trainings-Handbuch
ist als Kurs oder Trainingsprogramm organisiert
ist nach Aufgaben gegliedert:
Das Handbuch beschreibt die Wege zur Erreichung von Arbeitszielen.
Beispiel: So buchen Sie eine Anmeldung
Die n otigen Arbeitsabl aufe bestimmen die Gliederung.
mu von Anfang bis Ende vollst andig durchgearbeitet werden
erfordert direkte Arbeit mit demProdukt, d.h. der Leser f uhrt die Anweisungen des Trainings-
Handbuchs aus
vermittelt rasch Erfolgserlebnisse
ist f ur fortgeschrittene Benutzer und Experten zu elementar
8.3.2 Referenz-Handbuch
F ur Experten bestimmt.
Ein Referenz-Handbuch
erm oglicht schnellen Zugriff auf spezische Information
ist nach Produktaufbau gegliedert:
Alle Funktionen und Bestandteile werden in der Reihenfolge beschrieben, die sich
aus der Struktur des Produktes ergibt.
Beispiel: Die Funktion
Anmeldungen bearbeiten
103
Es wird beschrieben, was das Produkt kann. . .
. . . und nicht, wie man Arbeitsziele mit dem Produkt erreicht
bietet vollst andige Informationen zu allen Produktfunktionen
unterstellt, da der Benutzer mehr wei, als er tun will
8.3.3 Referenzkarte
Ebenfalls f ur Experten bestimmt.
Eine Referenzkarte
fat die wesentlichen Informationen der wichtigsten oder h augsten Funktionen zusam-
men.
ist m oglichst kompakt (nicht mehr als eine A4-Seite)
Abwandlung: die Referenztasse.
8.3.4 Benutzer-Leitfaden (user guide)
F ur fortgeschrittene Benutzer gedacht.
Ein Leitfaden
ist eine Mischform aus Trainings- und Referenzhandbuch
mu simultan die Bed urfnisse beider Benutzergruppen, Anf anger und Experten, erf ullen.
besteht typischerweise aus zwei Teilen:
Die aufgabenorientierte Arbeitsanleitung dient zum Einarbeiten.
nicht vollst andig
erlaubt das Arbeiten mit Grundfunktionen.
Der Referenzteil dient zum sp ateren Nachschlagen.
erlaubt es, sich die weiteren Funktionen zu erschlieen.
erlaubt es, bereits bekannte Informationen zu uberschlagen
darf aber nicht davon ausgehen, da der Leser Systemdetails bereits kennt
bei einfachen Systemen das einzige Handbuch
Bei umfangreichen Systemen gibt es oft alle vier Handbuch-Typen!
104
8.4 Aufbau eines Benutzer-Handbuchs
F ur Benutzer-Handb ucher l at sich kein generelles Gliederungsschema wie etwa Pichtenhefte
(Abschnitt 7.2.1)vorgeben. Neben dem sachlichen Inhalt geh oren aber bestimmte Teile in jedes
Handbuch:
Vorwort
Enth alt Adressatenkreis, Anwendungsbereich,
Anderungen gegen uber Vorversionen.
Ziel: der Leser mu nach den ersten Seiten wissen, ob Produkt und Handbuch f ur ihn und
seine Anwendung bestimmt sind.
Manche Leser uberbl attern das Vorwort; deshalb geh oren unverzichtbare Informationen in
die Einleitung.
Inhaltsverzeichnis
Einf uhrung
Dient in der Regel als Gebrauchsanleitung, die uber den Aufbau und den Umgang mit dem
Handbuch informiert.
Beschreibt oft auch
die Konguration, die f ur das Produkt erforderlich ist (evtl. in eigenem Kapitel).
Zielgruppe
Vorkenntnisse zum Verstehen des Handbuchs
Insgesamt soll die Einf uhrung kurz sein.
Installation
Beschreibt, was der Benutzer tun mu, um das Produkt in Betrieb zu nehmen.
Wird nur selten gelesen, kann deshalb in den Anhang (dann mu aber in der Einf uhrung
darauf verwiesen werden).
Benutzungsober ache
Verdeutlicht den prinzipiellen Aufbau der Benutzungsober ache.
Insbesondere
Tasten- und Mausbelegung
grunds atzlicher Bildschirmaufbau (z.B. Fenstertypen)
Dialogstrategie (z.B. erst Objekt, dann Funktion ausw ahlen)
105
Produktstruktur
Gibt einen
Uberblick uber die einzelnen Bestandteile des Produkts.
Trainingsteil
(im Benutzer-Leitfaden oder Trainings-Handbuch)
Beschreibt typische Arbeitsabl aufe mit Beispielen und
Ubungen, mit besonderem Wert auf
Routinearbeiten.
Anordnung:
h augste Arbeitsabl aufe und Routinearbeiten
seltene Arbeitsabl aufe
Initialisieren und L oschen von Systemen
Beispiele m ussen aus dem geplanten Anwendungsbereich stammen
Abstraktionen (also var-1, var-2 statt zins und kapital) sind zu vermeiden
Ubungen sind so zu gestalten, da der Benutzer mit dem Produkt arbeitet und dabei
Erfolgserlebnisse hat.
Referenzteil
(im Benutzer-Leitfaden oder Referenz-Handbuch)
Enth alt eine vollst andige Beschreibung der einzelnen Objekte und Funktionen.
Die Anordnung orientiert sich meistens an der Men ustruktur.
Kommandos werden alphabetisch angeordnet.
Behandlung von Problemen
Enth alt eine Liste von Fehlermeldungen mit detaillierten Erkl arungen und Vorschl agen
Literaturverzeichnis
Abk urzungsverzeichnis
Glossar
Stichwortverzeichnis / Index / Register
Wichtigstes Hilfsmittel f ur einen schnellen Zugriff
Enth alt Benutzerziele (z.B. Anmeldung vornehmen) und Funktionsnamen (z.B. Buchung
erfassen)
Erstellt der Handbuch-Autor ein gutes Handbuch, dann sparen hunderte oder tausende
Benutzer eine Menge Zeit und Nerven!
106
8.5 Hilfesysteme
Ein Hilfesystem unterst utzt den Benutzer w ahrend der Benutzung durch explizite Erkl arungen
und Ausk unfte.
Schnelle und vom Kontext abh angige Erg anzung zum Benutzer-Handbuch
Hilfesysteme erl autern typischerweise folgende Punkte:
Aktuell w ahlbare Objekte, Funktionen, und Kommandos (und deren Optionen)
Bedeutung von Funktionstasten und Mauskn opfen
Hinweise zu Eingaben
Erl auterungen zu Funktionsergebnissen
Spezische Fehlererkl arungen (einschlielich Hilfen zur Korrektur)
Vorteile gegen uber dem Handbuch:
+ Texte in Hilfesystemen sind schneller und leichter zu aktualisieren.
+ Die Information in Hilfesystemen kann nicht verlorengehen.
Nachteile gegen uber dem Handbuch:
Der Text auf dem Bildschirm wird langsamer gelesen als in einem Handbuch (k urzer fas-
sen!)
Notizen und Markierungen wie auf Papier sind nicht m oglich.
Es gibt auch Mischformen aus Hilfesystemen und Handb uchern:
Es gibt Programme, die ausschlielich per Hilfesystem dokumentiert sind; lediglich die
Installationsanleitung kommt in gedruckter Form.
Bei manchen Programmen (z.B. Netscape) ist die gesamte Dokumentation als WWW-
Hypertext organisiert, auf den uber das Netz zugegriffen wird.
107
8.5.1 Dynamische Hilfesysteme
Ein statisches Hilfesystem liefert stets dieselbe Information, unabh angig vom Kontext.
Beispiel: in einem Fenster wird an jeder Stelle die gleiche Erkl arung gegeben.
Dies gilt auch bei Fehlermeldungen.
Beispiel: Der UNIX-Editor ed gibt bei Fehlern aller Art die Meldung
?
aus.
Ein dynamisches Hilfesystem ber ucksichtigt den Kontext zum Zeitpunkt der Hilfeanforderung.
Beispiel: In jedem Eingabefeld eines Fensters wird eine spezische Hilfe gegeben.
Dies gilt auch bei Fehlermeldungen.
Beispiel: Der eingegebene Wert 0.005 ist zu klein
Dynamische Hilfesysteme sind stets vorzuziehen.
8.5.2 Individuelle Hilfesysteme
Ein uniformes Hilfesystem gibt jedem Benutzer dieselbe Hilfe unabh angig von seinem Kenntnis-
stand.
Ein individuelles Hilfesystem unterscheidet nach verschiedenen Benutzergruppen (Anf anger, Ex-
perte).
Die Einstufung kann auch automatisch erfolgen.
Beispiel: Nachdem Sachbearbeiter M uller nur noch selten das Hilfesystem aufruft,
wird er als vom Hilfesystem als Experte eingestuft und erh alt nur noch eine Kurz-
form der Erkl arungstexte.
Individuelle Hilfesysteme sind stets vorzuziehen.
8.5.3 Passive und Aktive Hilfesysteme
Nur 40% der Funktionalit at komplexer Systeme werden auch benutzt.
Manche Funktionen werden nur selten benutzt, da der Benutzer
die Funktionen nicht im Detail kennt
sich unsicher uber ihre Details und Wirkungen ist
108
Das ist der Einsatzbereich von passiven Hilfesystemen.
Ein passives Hilfesystem erwartet, da der Benutzer von sich aus eine Hilfeleistung anfordert,
z.B.
durch Dr ucken einer Taste (F1 oder Help)
durch Eingabe eines Kommandonamens (man ls)
durch Anfragen in nat urlicher Sprache (
Sackgasse enden.
R uckmeldungen auf alle Benutzeroperationen. Anzeigen, ob Eingabe erwartet wird oder
gerade eine Verarbeitung stattndet.
Uberdurchschnittliche Verarbeitungszeiten anzeigen
(Art, Objekt, Umfang oder Dauer).
Systembedingte Verz ogerungen, Unterbrechungen oder St orungen explizit anzeigen.
112
Regelwerke f ur die Dialoggestaltung
Das wichtigste Hilfsmittel, einheitliche Programmbedienung zu erhalten, sind Regelwerke (style
guides) f ur die Ober achengestaltung.
Beispiel: Dialoggestaltung mit der GNOME-Bibliothek, einem Linux-Standard:
1
All dialogs should have at least one button that is labeled Close, Cancel, OK, or
Apply.
Modal dialogs should be avoided wherever possible.
The default highlighted button for a dialog should be the safest for the user.
All dialogs should default to a size large enough to display all of the information in the
dialog without making a resize necessary.
All dialogs should set the titlebar with an appropriate string.
A dialog which consists of a single entry box shall have its OK button be the default
(which is to say that ENTER shall accept the entry), and the ESCAPE key shall be bound to
the Cancel button.
In a dialog the OK or Apply button should not be highlighted until the user has made
a change to the congurable data in the dialog.
If a dialog contains more than one button for the destruction of that dialog, (for example,
an OK and a Cancel), the afrmative button should always fall to the left of the
negative.
Style Guides k onnen bis zu hundert Seiten umfassen!
Verbreitete Stile und Regelwerke der Dialoggestaltung sind
Windows (Windows Interface Application Design Guide)
Motif (OSF/Motif Style Guide)
MacOS (Macintosh Interface Guidelines)
Manche Betriebssysteme (z.B. X Window System/UNIX), Programme (z.B. StarOfce), und
Bibliotheken (z.B. Swing, Qt) unterst utzen mehrere Stile entweder wahlweise oder gleichzeitig.
Generell n ahern sich Aussehen und Verhalten der Ober achen (look and feel) zunehmend einan-
der an.
1
http://www.gnome.org/
113
Beispiele f ur inkonsistente Benutzeroperationen
2
Den Sinn einheitlicher Regeln f ur Benutzungsschnittstellen erkennt man am besten, wenn man
Verst oe betrachtet.
Auf einem Macintosh-M ulleimer kann man beliebige Objekte l oschen, indem man sie auf den
M ulleimer zieht.
Zieht man jedoch eine Diskette auf den M ulleimer, wird sie nicht gel oscht, sondern ausgeworfen.
Ein
palettized display?
Ein PC-Experte mag diese Meldung vielleicht verstehen. Diese Warnung entstammt aber Dr.
Zeusss ABC, ein Alphabet-Lern-Programm f ur 3- bis 5j ahrige Kinder.
Noch bemerkenswerter: Die Warnung ist v ollig uber ussig, denn auch ohne
palettized display
funktioniert das Programm einwandfrei.
Diese h ochst aussagekr aftige Fehlermeldung ist Microsoft Visual Basic 5.0 zu entnehmen:
Nach dem Klicken auf Help erhalten wir:
Visual Basic encountered an error that was generated by the system or an external
component and no other useful information was returned.
The specied error number is returned by the system or external component (usually
from an Application Interface call) and is displayed in hexadecimal and decimal
format.
Das bedeutet:
Irgendetwas ist passiert. Wir wissen nicht, was hier passiert ist oder warum es pas-
siert ist. Wir wissen nur, da die dargestellte hexadezimale Zahl eine hexadezimale
Zahl ist, aber die Zahl selbst hat keine Bedeutung.
Was nicht in der Erl auterung steht: Die L osung des Problems. Neu booten.
116
Zum Schlu eine unfreundliche Fehlermeldung der Secure Shell:
$ ssh somehost.foo.com
You dont exist, go away!
$
Diese Fehlermeldung erscheint etwa, wenn der NIS-Server gerade nicht erreichbar ist. Nicht, da
man den Benutzer dar uber aufkl aren w urde. . .
117
9.2.2 Erwartungskonforme Dialoge
Die Handlungskompetenz wird durch erwartungskonforme Dialoge unterst utzt.
Ein Dialog ist erwartungskonform, wenn er den Erwartungen der Benutzer entspricht,
die sie aus Erfahrungen mit bisherigen Arbeitsabl aufen oder aus der Benutzerschulung
mitbringen sowie
den Erwartungen, die sie sich w ahrend der Benutzung des Dialogsystems und im Umgang
mit dem Benutzerhandbuch bilden.
Konkrete Manahmen f ur erwartungskonforme Dialoge:
Das Dialogverhalten ist einheitlich (z.B. konsistente Anordnung der Bedienungselemente).
Bei ahnlichen Arbeitsaufgaben ist der Dialog einheitlich gestaltet (z.B. Standard-Dialoge
zum
Offnen oder Drucken von Dateien)
Zustands anderungen des Systems, die f ur die Dialogf uhrung relevant sind, werden dem
Benutzer mitgeteilt.
Eingaben in Kurzform werden im Klartext best atigt.
Systemantwortzeiten sind den Erwartungen des Benutzers angepat, sonst erfolgt eine
Meldung.
Der Benutzer wird uber den Stand der Bearbeitung informiert.
118
Beispiele f ur unerwartetes Dialogverhalten
Gew ohnlich schreiben Standards vor, wie Bedienungselemente anzuordnen sind etwa Best ati-
gen vor Abbrechen, oder Ja vor Nein, oder Hilfe ganz rechts. Microsoft Excel macht alles anders:
Wo ist der Unterschied zwischen Yes und OK?
Wenn man Freeloader, einen WWW-Browser deinstalliert, erscheint dieses Fenster:
Der Benutzer mag denken, er k onne ausw ahlen, was denn nun tats achlich deinstalliert werden
soll. Weit gefehlt! Dies ist eine Statusmeldung, die anzeigt, was bereits deinstalliert wurde.
Originellerweise andern die Kn opfe ihren Zustand, wenn man auf sie klickt aber diese
Ande-
rung hat keine Auswirkungen.
119
9.2.3 Fehlerrobuste Dialoge
Ein Dialog ist fehlerrobust, wenn trotz erkennbar fehlerhafter Eingaben das beabsichtigte Ar-
beitsergebnis mit minimalem oder ohne Korrekturaufwand erreicht wird.
Dem Benutzer m ussen Fehler verst andlich gemacht werden, damit er sie beheben kann.
Konkrete Manahmen f ur fehlerrobuste Dialoge:
Benutzereingaben d urfen nicht zu Systemabst urzen oder undenierten Systemzust anden
f uhren.
Aus der GCC-Dokumentation:
If the compiler gets a fatal signal, for any input whatever, that is a compiler bug. Reliable
compilers never crash.
Automatisch korrigierbare Fehler k onnen korrigiert werden. Der Benutzer mu hier uber
informiert werden.
Die automatische Korrektur ist abschaltbar.
Korrekturalternativen f ur Fehler werden dem Benutzerangezeigt.
Fehlermeldungen weisen auf den Ort des Fehlers hin. z.B. durch Markierung der Fehler-
stelle.
Fehlermeldungen sind
verst andlich,
sachlich und
konstruktiv
zu formulieren und sind einheitlich zu strukturieren (z.B. Fehlerart, Fehlerursache, Fehler-
behebung).
120
Beispiele f ur schlechte Fehlermeldungen
Dies ist eine Fehlermeldung von Eudora, einem E-Mail-Programm:
mismatch eintippte (
der Benutzer zur Ausf uhrung eines in seinem Verst andnis zusammenh angenden und ein-
heitlichen Arbeitsschrittes eine gr oere Anzahl von Interaktionsschritten ben otigt (gerin-
ge Efzienz der Mensch-Rechner-Interaktion).
Konkrete Manahmen zum Steigern der Efzienz:
Minimierung der Interaktionsschritte, die zur Ausf uhrung einer Aufgabe oder einer ein-
zelnen Operation ben otigt werden.
Hilfreiche Techniken:
Mnemonische Auswahl von Men uoptionen uber die Tastatur
Auswahl uber Tastaturk urzel (z.B. Strg+X statt BearbeitenAusschneiden)
Symbolbalken (Toolbar) mit h aug benutzten Funktionen
Auff uhrung der zuletzt benutzten Objekte / Einstellungen
Kommandosprache (ggf. mit Kontrollstrukturen)
Planungsaufwand reduzieren, z.B. durch syntaktisch einfache Aufgaben oder Reduktion
vieler Einzelschritte
Makro- und Mengenbildung (s. Abschnitt 9.3)
Syntaktische Fehler verhindern oder abfangen.
Uber ussige Systemmeldungen, die der
Benutzer quittieren mu, vermeiden.
Am besten ist die volle Funktionalit at eines Men usystems und einer Kommandosprache!
126
Beispiele f ur mangelnde Efzienz
Jedesmal, wenn man in Lotus Notes eine e-mail absenden will, verlangt Notes eine Best atigung.
Das kann auf Dauer recht anstrengend werden:
Wenn der Benutzer schon einmal auf Absenden gedr uckt hat, warum nicht einfach anerkennen,
da er wohl Absenden meint?
Noch schlimmer treibt es da AK-Mail:
Warum eigentlich JA? Warum nicht gleich JAAA, VERFLUCHT!?
Microsofts Web Wizard ist ein Programm zum Verwalten von Dateien auf WWW-Servern.
W ahrend des Ablaufs erstellt Web Wizard eine Liste der Dateien auf dem Server und fragt ab,
f ur jede Datei einzeln, ob sie gel oscht werden soll:
127
Wenn man etwa die Datei zeller.gif l oschen wollte, m ute man zun achst 400mal auf No klicken
f ur jede der Dateien, die im Alphabet davor stehen.
Sehr viel efzienter w are es hier, das Programm w urde einfach die komplette Liste der Dateien
anzeigen und L oschen von Gruppen anbieten.
Wenn man in Visual Basic einen Text selektiert und dann Search aufruft, wird der selektierte Text
zur Vorgabe. So sollte es sein.
In anderen Programmen wie etwa Notepad mu der Benutzer stattdessen aufwendig den Text
uber die Zwischenablage kopieren und einf ugen:
128
Beispiele f ur gute Efzienz
In den Textverarbeitungsprogrammen LyXund KLyXgibt es einen Formeleditor, mit demAnf anger
Formeln uber ein Men u zusammensetzen k onnen:
Der fortgeschrittene Benutzer kann aber auch direkt uber die Tastatur T
E
X-Kommandos eingeben
etwa
\sum_{n = 1}{\infty}\frac{xn}{n} =
\ln\left(\frac{1}{1 - x}\right)
f ur
n=1
x
n
n
= ln
_
1
1x
_
.
Bereits mit der ersten Eingabe von \ schaltet KLyX in den T
E
X-Eingabemodus.
Flexible Programme sind meist auch efzient!
129
9.5 Benutzerfreundliche Web-Seiten
Die Top 10, um die Benutzungsfreundlichkeit zu erh ohen von Jakob Nielsens Alertbox
3
:
1. Name und Logo auf alle Seiten
2. Suchfunktion (bei > 100 Seiten)
3. Aussagekr aftige Titelzeilen
4. Vertikales Scannen erm oglichen
5. Information per Hypertext strukturieren (statt Scrollen)
6. Kleine Photos benutzen
7.
Ubertragungsgeschwindigkeit maximieren
8. Links mit Titeln versehen
9. Seiten f ur Behinderte zug anglich machen
10. Konventionen von anderen Seiten ubernehmen
. . . und umgekehrt die Top 10, um die Benutzungsfreundlichkeit zu verringern:
1. Frames
2. Neueste Plug-Ins
3. Scrollender Text
4. Lange URLs
5. Waisenseiten (= Error 404)
6. Scrollende Navigations-Seiten
7. Keine Unterst utzung f ur Navigation
8. Eigene Farben f ur Links
9. Obsoleter Inhalt
10. Lange Ladezeiten
3
http://www.useit.com/alertbox/
130
9.6 Benutzerfreundlichkeit pr ufen
Umdie Benutzerfreundlichkeit zu pr ufen, gibt es nur ein Mittel: Das Systemmit echten Benutzern
testen!
Typische Vorgehensweise: Benutzer sollen mit dem System eine bestimmte Aufgabe erledigen
und halten anschlieend fest, was sie gest ort hat.
Beispiel: In Linux-Maschine einloggen (Studie, 2001)
4
Probleme bei der Benutzung dieses Dialogs:
Was ist ein
Uberschaubarkeit
Elemente sollten nicht zu gro sein
Gesamtziel: Lokalisierung Separation der Interessen und Evolutionsf ahigkeit
137
10.2 Chaos (1950)
Am Anfang der Programmierung gab es kaum explizite Programmelemente: selbst die Trennung
von Daten und Programmcode war anfangs unbekannt.
Das Programm konnte beliebig den kompletten Speicher manipulieren (und tat es auch).
Die Kommunikation selbst ist unstrukturiert:
Elemente manipulieren direkt Daten oder sogar Programmcode (Assembler!) von anderen Ele-
menten.
Dieser schwerwiegende Versto gegen das Geheimnisprinzip wird mit sofortigem Entzug des
Diploms geahndet!
(Leider) immer noch verbreitet: Daten werden uber globale Variablen ausgetauscht (z.B. COMMON-
Bl ocke in FORTRAN).
Dieser Versto gegen das Geheimnisprinzip ist nur in ganz wenigen Ausnahmesituationen
sinnvoll!
138
10.3 Parametrisierte Funktionen (1960)
Funktionen verf ugen uber lokale Variablen, auf die von auen nicht zugegriffen werden kann.
Kommunikation erfolgt uber Argumente bei Funktionsaufrufen.
Heute immer noch sicheres Standardverfahren!
Aber: Der Zustand des Systems wird nach wie vor in allgemein zug anglichen globalen Variablen
abgelegt.
Ein System kann auf mehrere Weisen in Funktionen zergliedert werden:
Top-Down-Entwurf
Eine Funktion wird solange in Sequenzen, Schleifen oder Abfragen zerlegt, bis man bei elemen-
taren Operationen angelangt ist. (vergl. Abschnitt 7.4.1)
Klassischer
Stack in MODULA-2
Modulkopf in MODULA-2 mit Signaturen:
DEFINITION MODULE stack;
PROCEDURE empty stack();
PROCEDURE push(x: integer);
PROCEDURE pop();
PROCEDURE top(): integer;
PROCEDURE isempty(): boolean;
END stack;
Verwendung in Anwender-Modul:
FROM stack IMPORT empty stack, push, pop, top;
.
.
.
empty stack();
push(42);
push(37);
WHILE NOT isempty() DO
WriteInt(top());
pop();
END;
145
Realisierung in MODULA-2 (mittels Feld fester Gr oe):
IMPLEMENTATION MODULE stack;
CONST size = 2500;
VAR s: ARRAY[1..size] OF integer;
c: [0..size];
PROCEDURE empty stack();
BEGIN
c := 0
END empty stack;
PROCEDURE isempty(): boolean;
BEGIN
RETURN c = 0
END isempty;
PROCEDURE push(x: integer);
BEGIN
c := c + 1;
s[c] := x
END push;
PROCEDURE pop();
BEGIN
c := c - 1
END pop;
PROCEDURE top(): integer;
BEGIN
RETURN s[c]
END top;
END stack;
(Fehlerbehandlung (Unter-/
Stack in Java
In Java sind abstrakte Datenobjekte eher ungew ohnlich; Vorgabe ist der abstrakte Datentyp
(Abschnitt 10.7)bzw. die Klasse (Abschnitt 10.9).
Abstrakte Datenobjekte werden als Klassen realisiert, bei denen alle Methoden und Variablen
mittels static als Klassenmethoden und Klassenvariablen deklariert sind.
public class Stack
// Klassenvariablen und -Konstanten
// (nicht-offentlich)
private static final int size = 500;
private static int s[] = new int[size];
private static int c = -1;
//
Offentliche Funktionen
public static void empty() c = -1;
public static void push(int x) s[++c] = x;
public static void pop() --c;
public static int top() return s[c];
public static boolean isempty() return c == -1;
Auf size, s, und c kann von auerhalb der Klasse nicht zugegriffen werden!
Verwendung:
public class demo
public static void main(String[] args)
Stack.empty();
Stack.push(45);
int x = Stack.top();
Stack.pop();
System.out.println("x = " + x);
147
10.6.3 Beispiel: Abstraktes Datenobjekt
Stack in C
In C kann mit dem Schl usselwort static die Sichtbarkeit eines Objekts auf die jeweilige
Uber-
setzungseinheit (= Datei) eingeschr ankt werden.
In einer Header-Datei sind auerdem genau die Dienste deklariert, auf die von auen zugegriffen
werden darf.
int x;
stack empty();
stack push(45);
x = stack top();
stack pop();
printf("x = %dn", x);
Ingenieur)
public class Control
// Direkter Zugang zu Sensor-Datenblock
public static int state[];
// Indizes der einzelnen Felder
public static final int PRESSURE = 0;
public static final int TEMP LOBYTE = 1;
public static final int TEMP HIBYTE = 2;
public static final int VALVES = 3;
// Bits in state[VALVES]
public static final int INPUT VALVE = 0x1;
public static final int OUTPUT VALVE = 0x2;
public static final int EMERGENCY VALVE = 0x4;
;
Zugriffsbeispiel:
int temperature =
Control.state[Control.TEMP LOBYTE] +
Control.state[Control.TEMP HIBYTE]
*
256;
if (temperature > 100)
Alarm.alarm("Feueralarm", 137);
Control.state[VALVES] |= EMERGENCY VALVE;
Control.state[VALVES] &= INPUT VALVE;
else
boolean input open = (state[VALVES] & INPUT VALVE) > 0);
Control.state[PRESSURE] = compute pressure(temperature);
.
.
.
Anderung der Hardware bedingt ( uberall)
Anderung des Programms
150
Variante 2 (
Fortgeschrittener Ingenieur)
class Control
// Direkter Zugang zu Sensor-Datenblock
public static int state[];
// Indizes der einzelnen Felder
public static final int PRESSURE = 0;
.
.
.
// Bits in state[VALVES]
public static final int INPUT VALVE = 0x1;
public static final int OUTPUT VALVE = 0x2;
public static final int EMERGENCY VALVE = 0x4;
// Zugriffsfunktionen
public static int get temperature()
return state[TEMP LOBYTE] + state[TEMP HIBYTE]
*
256;
.
.
.
;
Schon besser, da jetzt Zustand uber Zugriffsfunktionen zug anglich.
Aber:
Nach wie vor direkter Zugang zum Zustand (state) m oglich
Nach wie vor werden Zustands-Interna nach auen sichtbar (hier: die Codierung der Ven-
tile)
151
Variante 3 (
Software-Ingenieur)
public class Control
// Zugriffsfunktionen
public static int get temperature() ...
public static boolean input valve open()
return valve open(INPUT VALVE);
// Interne Funktionen
private static void set valve(int valve, boolean valve open)
if (valve open)
state[VALVES] |= valve;
else
state[VALVES] &= valve;
.
.
.
// Interner Zustand
private static int state[];
// Interne Konstanten
private static final int PRESSURE = 0;
private static final int TEMP LOBYTE = 1;
.
.
.
Stack in Java
In Java werden ADTs als Klassen realisiert.
public class Stack
// Instanzvariablen und Klassenkonstanten
static final int size = 500;
int s[] = new int[size];
int c = -1;
//
Offentliche Funktionen
public void empty() c = -1;
public void push(int x) s[++c] = x;
public void pop() --c;
public int top() return s[c];
public boolean isempty() return c == -1;
Verwendung:
public class demo
public static void main(String[] args)
Stack s = new Stack();
s.empty();
s.push(45);
int x = s.top();
s.pop();
System.out.println("x = " + x);
Stack in C
In C benutzt man opake Zeiger zum Realisieren von ADTs.
In stack.h ist stack als Zeiger auf ein stackrep (= stack representation) deniert, der ge-
naue Aufbau von stackrep fehlt jedoch. Deshalb kann von auen nicht auf Interna des ADT
zugegriffen werden.
stackrep wird in einer privaten Header-Datei deniert, die Zugang zu den Interna erm oglicht:
Private Deklarationen stackP.h:
#define STACK SIZE 500
struct stackrep
int s[STACK SIZE];
int c;
;
Die Implementierung greift auf stackP.h zur uck:
#include "stack.h"
#include "stackP.h"
155
stack new stack()
stack st = malloc(sizeof(struct stackrep));
stack empty(st);
return st;
.
.
.
Auch hier k onnen Realisierungs-Details nach Belieben ver andert werden, solange die Schnitt-
stelle gleich bleibt.
156
10.7.3 Beispiel: Abstrakter Datentyp
Stack in MODULA-2
Auch in Modula-2 benutzt man opake Zeiger zum Realisieren von ADTs.
DEFINITION MODULE stack;
TYPE stacktype; (
*
opaker Typ
*
)
PROCEDURE new(): stacktype;
PROCEDURE push(s: stacktype; x: integer): stacktype;
PROCEDURE pop(s: stacktype): stacktype;
PROCEDURE top(s: stacktype): integer;
PROCEDURE delete(s: stacktype);
PROCEDURE isempty(s: stacktype): boolean;
END stack;
Verwendung:
FROM stack IMPORT stacktype, new, delete, push, pop, top;
VAR s1, s2: stacktype;
.
.
.
s1 := new();
s2 := new();
s1 := push(s1, 42);
s2 := push(s2, 17);
s1 := push(s1, 103);
s1 := pop(s1);
WHILE NOT isempty(s2) DO
WriteInt(top(s2));
s2 := pop(s2)
END;
delete(s1);
delete(s2);
157
Realisierung in MODULA-2 (mittels Feld fester Gr oe):
IMPLEMENTATION MODULE stack;
CONST size = 100;
TYPE stacktype = POINTER TO RECORD
s: ARRAY[1..size] OF integer;
c: [0..size]
END;
PROCEDURE new(): stacktype;
VAR st: stacktype;
BEGIN
NEW(st);
st.c := 0;
RETURN st
END new;
PROCEDURE push(s: stacktype; x: integer): stacktype;
.
.
.
PROCEDURE pop(s: stacktype): stacktype;
.
.
.
PROCEDURE top(s: stacktype): integer;
.
.
.
PROCEDURE delete(s: stacktype);
.
.
.
PROCEDURE isempty(s: stacktype): boolean;
.
.
.
END stack;
158
10.8 Generische Datenobjekte und Datentypen (1985)
Ein generischer Datentyp realisiert einen parametrisierten abstrakten Datentyp. Bestandteile des
Typs sind variabel z.B. der Objekttyp bei Containern.
Geht explizit nur in manchen Sprachen:
Ada generische Pakete
C++ Templates
Java generische Klassen
Funktionale Sprachen Polymorphismus
10.8.1 Beispiel: Generisches Datenobjekt
Stack in Ada
Modulkopf:
GENERIC
size: NATURAL; (
*
Parameter des generischen ADO
*
)
TYPE item IS PRIVATE;
PACKAGE stack IS
TYPE stacktype IS PRIVATE;
PROCEDURE emptystack() RETURN stacktype;
PROCEDURE push(s: IN stacktype; x: IN item)
RETURN stacktype;
PROCEDURE pop(s: IN stacktype) RETURN stacktype;
PROCEDURE top(s: IN stacktype) RETURN item;
END stack;
Verwendung im Anwender-Modul:
PACKAGE integer stack IS
NEW stack(size => 100, item => INTEGER);
PACKAGE string stack IS
NEW stack(size => 500, item => STRING);
VAR
s1: integer stack;
s2: string stack;
.
.
.
s1 := emptystack();
s2 := emptystack();
s1 := push(s1, 42);
s2 := push(s2, hugo);
159
Vorteil: Allgemeinheit, viel bessere Wiederverwendbarkeit
160
10.8.2 Beispiel: Generischer Datentyp
Stack in Java
Java Generics wurden 1997 in Pizza, einem Java-Dialekt, vorgestellt und sp ater in Java 1.5 uber-
nommen.
public class Stack<E>
// Instanzvariablen und Klassenkonstanten
static final int SIZE = 500;
E s[] = new E[SIZE];
int c = -1;
//
Offentliche Funktionen
public void empty() c = -1;
public void push(E x) s[++c] = x;
public void pop() --c;
public E top() return s[c];
public boolean isEmpty() return c == -1;
public boolean isFull() return c == SIZE;
Verwendung:
Stack<Integer> values = new Stack<Integer>();
values.push(42);
Stack<String> pizza = new Stack<String>();
pizza.push("Salami");
pizza.push("Kase");
pizza.push("Knoblauch");
pizza.push("Knoblauch");
pizza.push("Knoblauch");
Vorteil: Allgemeinheit, viel bessere Wiederverwendbarkeit
Analog f ur generische abstrakte Objekte.
161
10.9 Objekte und Klassen (1990)
Eine Klasse ist ein (anderes Wort f ur) abstrakter Datentyp.
Ein Objekt ist ein Exemplar eines abstrakten Datentyps.
10.9.1 Klassen
Wie ein Modul besteht auch eine Klasse aus einer Schnittstelle und einer Implementierung.
Die Schnittstelle speziziert die Methoden (Funktionen, Operationen) der Objekte der
Klasse, uber die auf den internen Zustand zugegriffen werden kann.
Die Implementierung deniert die Methodenr umpfe und die Zustandsvariablen (Instanz-
variablen, Eigenschaften, Attribute) der Objekte.
Beispiel: Klasse Account zur Verkapselung eines Kontos (UML-Darstellung)
Syntax Attribute (alle Teile bis auf attribut sind optional):
attribut[Multiplizit at] : Paket : : Typ = InitialwertZusicherungen
Syntax Methoden (alle Teile bis auf methode sind optional):
methode(Argumentliste): R uckgabetypZusicherungen
Der Pr ax gibt die Sichtbarkeit an (+: public, : private)
162
10.9.2 Objekte
Ein Objekt ist eine bestimmtes Exemplar (engl. instance) einer Klasse.
Es kann beliebig viele Objekte einer Klasse geben.
Objekte k onnen zur Laufzeit erzeugt werden.
Jedes Objekt einer Klasse hat einen eigenen Zustand (eigene Objekt- oder Instanzvariablen (engl.
instance variables) oder auch Attribute oder Fields genannt), aber dieselben Methoden.
Beispiel: Objekt konto 333 der Klasse Account
konto_333: Account
balance = 10000
minimum_balance = 0
owner = "Welthungerhilfe"
Objektname
und Klasse
Attribute
Die Methoden werden nicht explizit aufgef uhrt.
Beziehung zwischen Objekt und Klasse:
Account konto_333
<<instance of>>
163
10.9.3 Vererbung
Die zentrale Erweiterung im Objektorientierten Software-Entwurf ist: Eine Klasse (
Unterklas-
se) kann als Spezialisierung einer anderen Klasse (
// Nicht-offentliche Methoden
void add(double sum)
balance = balance + sum;
//
Offentliche Methoden
public void open(String who) owner = who;
public void deposit(double sum) add(sum);
public void withdraw(double sum) add(-sum);
public boolean may_withdraw(double sum)
return balance - sum >= minimum_balance;
.
.
.
Verwendungsbeispiel:
Account a1 = new Account("Fritz Brause", 0.00);
Account a2 = new Account("Richard Wagner", -1000.00);
Account a3 = new Account("Andreas Zeller", -5000.00);
167
10.9.6 Einfache Vererbung
Die verschiedenen Konten-Varianten werden als Spezialisierung der gemeinsamen Oberklasse
Account dargestellt.
Klassendenition
public class Checking_Account extends Account
double overdraft_limit;
public void set_overdraft_limit(double limit)
overdraft_limit = limit;
168
Klassen-Kompatibilit at
Objekte einer Unterklasse k onnen auch als Objekte der Oberklasse verwendet werden, da sie
alle Attribute und Methoden der Oberklasse haben; entsprechende Zuweisungen sind erlaubt.
Das umgekehrte gilt jedoch nicht!
.
.
.
Checking_Account a4 = new Checking_Account();
Loan_Account a5 = new Loan_Account();
a4.open("Walther Leisler Kiep");
a4.set_overdraft_limit(20000.00);
a5.open("CDU");
a5.set_interest_rate(20.00);
Account a1 = a4; // Ok
Account a2 = a5; // Ok
a1.deposit(500.00); // Ok
a1.withdraw(42.00); // Ok
if (a2.may_withdraw(5.00)) ... // Ok
1
a1.set_overdraft_limit(10000.00); // Verboten
=> Error: Method set_overdraft_limit(double)
not found in class Account
a2.set_interest_rate(10.00); // Verboten
=> Error: Method set_interest_rate(double)
not found in class Account
a4 = a1; // Verboten
=> Error: Incompatible type for =.
Explicit cast needed to convert Account
to Checking_Account.
a4 = a5; // Verboten
=> Error: Incompatible type for =.
Cant convert Loan_Account to Checking_Account.
.
.
.
1
Welche Methode wird hier aufgerufen? Siehe Abschnitt 10.9.7!
169
10.9.7 Dynamische Bindung
Jedes Objekt einer Unterklasse kann auch als Objekt der Oberklasse fungieren.
Unterklassen k onnen Oberklassenmethoden umdenieren. Deswegen kann man nur zur Laufzeit
bestimmen, welche Methode tats achlich aufgerufen wird.
Beispiel: Einrichten eines neuen Kontos
.
.
.
Account a;
if (kontentyp.einlesen())
a = new Loan_Account();
else
a = new Checking_Account();
if (a.may_withdraw(5.00)) ...
.
.
.
Welche may withdraw-Methode wird hier aufgerufen?
Wenn a auf ein Loan Account-Objekt verweist: die von Loan Account
Wenn a auf ein Checking Account-Objekt verweist: die von Checking Account
Diese dynamische Bindung (von Methoden-Aufrufen an Methoden-Denitionen) ndet zur Lauf-
zeit (dynamisch) statt im Gegensatz zur (herk ommlichen) statischen Bindung, die bereits beim
Ubersetzen stattndet.
170
Beispiel: Denition einer Grak
public abstract
2
class Shape
public abstract double area();
171
Benutzung:
// Feld von Shapes
Shape shapes[] = new Shape[3];
shapes[0] = new Circle(2.0);
shapes[1] = new Rectangle(1.0, 3.0);
shapes[2] = new Rectangle(4.0, 2.0);
// Flachen aufsummieren
double total_area = 0.0;
for (int i = 0; i < shapes.length; i = i + 1)
total_area = total_area + shapes[i].area();
Auch hier wird f ur jedes Element dynamisch bestimmt, welche area()-Methode aufgerufen
wird.
2
Shape ist ein Beispiel f ur eine abstrakte Oberklasse, die nur das Auenverhalten, nicht jedoch den vollst andi-
gen inneren Aufbau beschreibt: f ur wenigstens eine Methode fehlt die Implementierung (hier area()). Solche
abstrakten Methoden werden in den konkreten (nicht-abstrakten) Unterklassen deniert. Abstrakte Klassen k onnen
nicht instantiiert werden es gibt nur konkrete Objekte.
3
protected-Elemente sind f ur Unterklassen zug anglich
4
static-Elemente werden von allen Objekten geteilt; final steht f ur Elemente und Methoden, die von Un-
terklassen nicht redeniert werden k onnen PI ist also eine Konstante.
172
Dynamische Bindung vs. Fallunterscheidung
Bei herk ommlichem Entwurf ohne dynamische Bindung mu eine Fallunterscheidung herhalten,
um unterschiedliche Objekte gleichzeitig zu verwalten.
Beispiel mit varianten Records in MODULA-2:
PROCEDURE area(s: Shape): REAL
BEGIN
CASE s.typeid OF
Circle:
RETURN PI
*
s.circle.radius
*
s.circle.radius;
Rectangle:
RETURN s.rectangle.width
*
s.rectangle.height;
.
.
.
END
Nachteil: Bei jeder Einf uhrung eines neuen Shape-Typs m ussen s amtliche Fallunterscheidungen
uberpr uft und ggf. erweitert werden immenser Aufwand!
Mit dynamischer Bindung hingegen ist noch nicht einmal eine Neu ubersetzung der bisherigen
Klassen n otig.
Dynamische Bindung vs. Statische Bindung
Dynamische Bindung ist durch das Aufsuchen der geeigneten Methode geringf ugig teurer als die
(herk ommliche) statische Bindung, die bereits beim
Ubersetzen stattndet.
Oft kann der
Ubersetzer aber erkennen, da nur eine Methode in Frage kommt, und deshalb
statisch binden.
Beispiel:
Shape s = new Rectangle(1.0, 2.0);
double area = s.area();
Hier kann nur die area()-Methode von Rectangle in Frage kommen; der area()-Aufruf
kann statisch gebunden werden.
In der Praxis: Optimierung durch Sprungtabellen, nicht redenierbare Methoden (nicht-virtual
in C++) oder nicht erweiterbare Klassen (final in Java).
173
10.9.8 Mehrfache Vererbung
Mehrfache Klassenvererbung
Bei der Erstellung von Vererbungshierarchien kann es zu mehrfacher Vererbung kommen:
PCHndler Bcker
Kaufmann Rennfahrer
Geschftsmann Sportler
Mensch
Sportstudent Informatikstudent
Student
Ein B acker und ein Informatikstudent haben alle Eigenschaften eines Menschen (sowie weitere);
ein Sportstudent hat alle Eigenschaften von Sportlern und Studenten (sowie ggf. weitere).
Ein Problem bei mehrfacher Vererbung ist der Konikt bei mehrfacher Vererbung von Imple-
mentierungen: Wenn Sportler und Student unterschiedliche aufstehen()-Methoden im-
plementieren welche Implementierung wird dann in Sportstudent geerbt?
Weitere Probleme bei mehrfacher Vererbung sind:
Efzienz der dynamischen Bindung (Durchsuchen der Klassenhierarchie),
mehrfaches Erben von Oberklassen (ein gemeinsames Exemplar der Oberklasse oder
mehrere getrennte?)
174
Schnittstellenvererbung
In Java werden die Probleme der mehrfachen Klassenvererbung mit Hilfe von Interfaces (Schnitt-
stellen) umgangen:
Interfaces sind abstrakte Oberklassen, die keine Attribute enthalten d urfen.
Eine Klasse kann von mehreren Interfaces erben und mu alle abstrakten Methoden der
Interfaces implementieren (d.h. die Schnittstellen realisieren).
Interfaces k onnen ebenfalls von anderen (ggf. mehreren) Interfaces erben.
In unserem Beispiel k onnte dies so aussehen:
public interface Mensch ...
public interface Sportler extends Mensch
public void aufstehen();
public void sport_treiben();
Sportstudent k onnte hier auch als Interface realisiert werden, um weitere mehrfache Verer-
bung zu erm oglichen (z.B. einen PCs verkaufenden, Sportinformatik studierenden B acker).
Eine gesonderte Klasse Konkreter Sportstudent m ute dann das Interface Sportstudent
realisieren:
public interface Sportstudent extends Sportler, Student
// Keine neuen Methoden
175
Beispiel: Chemische Prozesteuerung mit Interfaces
Eine weiter verbesserte chemische Prozesteuerung aus Abschnitt 10.6.4:
public interface Control
// Zugriffsfunktionen
public int get temperature();
public boolean get input valve();
public void
set input valve(boolean new state);
;
public class RaffinerieControl implements Control
// Zugang zu Sensor-Datenblock
private int state[];
// Indizes der einzelnen Felder
private static final int PRESSURE = 0;
private static final int TEMP LOBYTE = 1;
private static final int TEMP HIBYTE = 2;
private static final int VALVES = 3;
// Bits in state[VALVES]
private static final int INPUT VALVE = 0x1;
private static final int OUTPUT VALVE = 0x2;
private static final int EMERGENCY VALVE = 0x4;
public int get temperature()
return state[TEMP LOBYTE] +
state[TEMP HIBYTE]
*
256;
.
.
.
;
Neue Steuerungshardware wird durch eine neue Klasse realisiert, die das Control-Interface
implementiert. Das Control-Interface (und der Rest des Programms) bleiben unver andert.
176
10.9.9 Vorteile des Vererbungsmechanismus
Trennung der gemeinsamen Eigenschaften von Objektmengen von individuellen Eigen-
schaften von Objekten
Hierarchische Klassikation von Objekten
Konstruktion allgemeiner Klassen, die spezialisiert werden k onnen
Wiederverwendung durch Ableitung neuer Klassen aus alten
Parametrisierte Klassen erlauben universell anwendbare Bausteine
Beispiel: Die Standard Template Library in C++
Schrittweise Evolution von Modulen durch Redenition/Hinzuf ugen von Funktionen in
einer Unterklasse
Varianten k onnen als Unterklassen einer Klasse beschrieben werden; die Unterklassen ent-
halten nur die variantenspezischen Funktionen
177
10.10 Subjekte und Aspekte (2000)
M ogliches Problem bei objektorientierter Modellierung: Crosscutting Concerns.
Bei der Separation der Interessen eines Systems kann es geschehen, dass sich Eigenschaften
miteinander uberschneiden und sich nicht sauber separieren lassen.
Ublicherweise wird die als wichtiger erscheinende Eigenschaft vorgezogen und gekapselt.
Die sekund are Eigenschaft, der Crosscutting Concern, bleibt ungekapselt
Standardbeispiel: Logging
Es gibt einige Ans atze zur Behandlung von Crosscutting Concerns:
Aspect-oriented Programming Crosscutting Concerns werden in sog. Aspekten gekapselt. Die
Punkte des Programms, an denen der Aspekt ausgef uhrt werden soll, k onnen durch Regeln
beschrieben werden. Ein sog. Aspect Weaver f ugt beim Kompilieren den Aspekt-Code an
diesen Punkten ein.
Feature-oriented Programming S amtliche Eigenschaften eines Programms werden in sog. Fea-
tures gekapselt. Aus ihnen kann dann das Programm synthetisiert werden. Dazu m ussen
allerdings auch die Funktionen f ur die Synthese entwickelt werden. Daher ist dieser Ansatz
vor allem auf Produktfamilien bezogen.
Subject-oriented Programming ist ein Ansatz zur Komposition von objektorientierten Pro-
grammen aus Subjekten. Ein Subjekt besteht aus einer Sammlung von Klassen oder Klas-
senfragmenten mit einer bestimmten Aufgabe.
Die Subjekt-Komposition kombiniert die Klassen der einzelnen Subjekte; das Resultat ist
wiederum ein Subjekt.
Schwierigkeit dabei: Regeln zur Komposition von Subjekten m ussen erstellt werden.
178
Kapitel 11
Objektorientierter Entwurf
In diesem Kapitel werden wir untersuchen, wie die Komponenten eines Systems in Hinblick auf
Gemeinsamkeiten und sp atere
Anderungen ausgesucht werden.
Hierzu dient uns der objektorientierte Entwurf.
11.1 Objektorientierte Modellierung
Die Objektorientierte Modellierung mit UML umfat u.a. folgende Aspekte des Entwurfs:
Objekt-Modell:
Welche Objekte ben otigen wir?
Welche Merkmale besitzen diese Objekte? (Attribute, Methoden)
Wie lassen sich diese Objekte klassizieren? (Klassenhierarchie)
Welche Assoziationen bestehen zwischen den Klassen?
Sequenzdiagramm:
Wie wirken die Objekte global zusammen?
Zustandsdiagramm:
In welchen Zust anden benden sich die Objekte?
179
11.2 Objekt-Modell: Klassendiagramm
Darstellung der Klassen als Rechtecke, unterteilt in
Klassenname,
Attribute m oglichst mit Typ (meistens ein Klassenname)
Methoden m oglichst mit Signatur
Darstellung der Vererbungshierarchie ein Dreieck (Symbol: ) verbindet Oberklasse und Un-
terklassen.
Beispiel f ur Vererbung: Konten
1
(Vergleiche Abschnitt 10.9.3)
Account
-balance: double
-minimum_balance: double
-owner: string
+open()
+deposit()
+withdraw()
+may_withdraw()
Checking_Account
-overdraft_limit: double
+set_overdraft_limit()
+may_withdraw()
+print_account_statement()
Loan_Account
-interest_rate: double
-amortization_amount: double
+set_interest_rate()
+may_withdraw()
Ererbte Methoden (wie hier: open(), deposit()) werden in der Unterklasse nicht mehr ge-
sondert aufgef uhrt.
Wird eine Methode wie may withdraw() in Unter- und Oberklasse aufgef uhrt, so uberschreibt
die Denition in der Unterklasse die Denition in der Oberklasse.
1
Die Beispiele dieses Kapitels sind entnommen aus: G. Goos, Vorlesungen uber Informatik. Band 2: Objektori-
entiertes Programmieren und Algorithmen, Springer 1996, sowie Bernd Oestereich, Objektorientierte Softwareent-
wicklung, Oldenbourg 1998.
180
Modier f ur Methoden und Attribute
+ f ur public
- f ur private
f ur protected
statische Methoden und Attribute werden unterstrichen
181
11.2.1 Abstrakte Klassen und Methoden
Klassen, von denen keine konkreten Objekte erzeugt werden k onnen, heien abstrakte Klassen.
Sie verf ugen meist uber eine oder mehrere abstrakte Methoden, die erst in Unterklassen realisiert
werden.
Eine konkrete Klasse ist eine Klasse, von der konkreten Objekte erzeugt werden k onnen.
Beispiel f ur abstrakte Klassen: Digitale Abspielger ate
Ein
ist ein Rechteck. Ist Square eine Unterklasse von Rectangle, verletzt
set a die Zusicherung von Square.
Rectangle
-a: double = 10 {a > 0}
-b: double = 10 {b > 0}
+area(): double
+draw()
+set_a(length:double)
+set_b(length:double)
Square
{a = b}
?
2
Man k onnte Real mit einer eigenen Implementierung von set imag versehen. Deren Vorbedingung
imag == 0 w urde aber ebenfalls zu einer Spezialisierung f uhren.
184
11.2.4 Ziel: Konformanz
Konformanz bedeutet, da ein Objekt einer Unterklasse in jeder Beziehung als Objekt der Ober-
klasse einsetzbar ist.
Klassenhierarchien sollten so konstruiert werden, da Konformanz stets sichergestellt ist.
In folgendem Beispiel ist die Konformanz verletzt. Von einer existierenden Klasse TextFile
hat ein Programmierer eine Klasse f ur bin are Dateien abgeleitet, um deren Methoden zu erben
(sogenanntes Erben von Implementierungen).
TextFile
-s: stream = void {nur ASCII-Zeichen}
+put(c:char)
+get(): char
BinaryFile
+put(b:byte)
+get(): byte
ruft TextFile.put(b) auf
?
Die Methoden des BinaryFile verletzen jedoch die Zusicherung des TextFile.
Selbst wenn die Methoden von TextFile funktionieren sollten wird irgendwo im Programm
ein TextFile erwartet, das die Zusicherung erf ullt, stattdessen jedoch ein BinaryFile uber-
geben, kann dies zu beliebigen Problemen f uhren.
Das Gegenst uck zur Konformanz ist die Spezialisierung. Bei ihr kann ein Objekt der Unterklasse
nicht in jeder Beziehung als Objekt der Oberklasse eingesetzt werden. Spezialisierung tritt vor
allem beim Ererben von Implementierungen auf. Soll Spezialisierung vermieden werden, sollte
das Erben von Implementierungen ausbleiben. Die Alternative ist das Benutzen von anderen
Klassen (ohne Vererbung), wobei Teile der Schnittstelle nachgebildet werden (sog. Delegation).
In unserem Beispiel k onnte BinaryFile ein TextFile benutzen, um Bin ardaten (in ASCII-
Zeichen kodiert) abzulegen.
185
Auch ohne explizite Zusicherungen kann die Konformanz verletzt sein.
Rectangle l at sich als Unterklasse von Square einrichten, wobei man die Kantenl ange a erbt:
Square
-a: double = 10 {a > 0}
+area(): double
+draw()
+set_a(length:double)
Rectangle
-b: double = 10 {b > 0}
+area(): double
+draw()
+set_b(length:double)
?
Auch hier ist die Konformanz verletzt: Wird irgendwo ein Quadrat bearbeitet, jedoch ein Recht-
eck ubergeben, wird nur die Kantenl ange a ber ucksichtigt.
Im Fall reelle/komplexe Zahlen k onnte eine solche Anordnung jedoch Sinn machen: Jede kom-
plexe Zahl kann als reelle verwendet werden (wobei die Funktionalit at auf den Realteil be-
schr ankt ist).
Real
-real: double = 0.0
+set_real(real:double)
Complex
-imag: double = 0.0
+set_imag(imag:double)
Frage ist, ob eine solche implizite Umwandlung von komplexen in reelle Zahlen nicht mehr
Risiken als Nutzen bringt.
186
Um tats achlich Quadrate und Rechtecke zu modellieren, bieten sich zwei Wege an. Man kann
Quadrate und Rechtecke als separate Klassen modellieren, die durch eine neue gemeinsame
Oberklasse verbunden sind:
Quadrangle
+area(): double
+draw()
+get_a(): double
+get_b(): double
Square
-a: double = 10 {a > 0}
+get_a(): double
+get_b(): double
+set_a(a:double)
Rectangle
-a: double = 10 {a > 0}
-b: double = 10 {b > 0}
+get_a(): double
+get_b(): double
+set_a(length:double)
+set_b(length:double)
gibt a zurck
Alternativ kann man sich auf den Standpunkt stellen, da jedes Rechteck ein Quadrat sein kann
n amlich dann, wenn die beiden Seiten gleich lang sind.
Man k onnte also auf eine eigene Klasse f ur Quadrate verzichten und stattdessen Rechtecke um
eine besondere Methode is square erweitern:
Rectangle
-a: double = 10 {a > 0}
-b: double = 10 {b > 0}
+area(): double
+draw()
+set_a(length:double)
+set_b(length:double)
+is_square(): boolean
return a == b
Nach dem gleichen Muster k onnen auch Text-/Bin ar-Dateien und reelle/komplexe Zahlen mo-
delliert werden.
187
11.2.5 Schnittstellen
Schnittstellen (vergl. Abschnitt 10.9.8)sind mit dem Schl usselwort interface gekennzeichnet.
Die implementierungs-Beziehung ist gestrichelt dargestellt und besitzt einen geschlossenen, nicht
ausgef ullten Pfeil.
Beispiel: Eine Person realisiert sowohl eine Patienten- als auch eine Arbeitnehmerschnittstelle
Kurzschreibweise mit
Lolli
Person
-gesundheit
-qualifikation
+get_gesundheit()
+get_qualifikation()
Patient
Arbeitnehmer
188
11.3 Objekt-Modell: Assoziationen
11.3.1 Allgemeine Assoziationen
Verbindungen zwischen nicht-verwandten Klassen stellen Assoziationen (Relationen) zwi-
schen Klassen dar
Diese beschreiben den inhaltlichen Zusammenhang zwischen Objekten (vgl. Datenbanktheo-
rie!)
Durch Multiplizit aten wird die Anzahl der assoziierten Objekte eingeschr ankt.
Beispiel f ur Assoziationen mit Multiplizit atsangaben:
Ein Rechnerh andler hat mehrere Kunden, ein Zusteller hat mehrere Kunden, aber ein Rech-
nerh andler hat nur einen Zusteller
Kunde
-name: string
-adresse: string
Zusteller
-name: string
-adresse: string
Rechnerhndler
-name: string
-adresse: string
ist kunde von 0..*
1
ist kunde von 0..*
1
ist zusteller von
0..*
1
189
Beispiel: Professoren haben mehrere Studenten, Studenten haben mehrere Professoren
Professor
-name: string
Student
-name: string
hrt bei 0..*
0..*
Beispiel f ur Objektbeziehungen:
p1: Professor
name = "Gregor"
p2: Professor
name = "Andreas"
s1: Student
name = "Georg"
s4: Student
name = "Grete"
s3: Student
name = "Gustav"
s2: Student
name = "Gerda"
hrt bei
hrt bei
hrt bei
hrt bei
Darstellung von Exemplaren (Objekten) mit unterstrichenem Objektnamen f ur die Attribute
sind konkrete Werte angegeben
190
11.3.2 Aggregation
Eine h aug auftretende und deshalb mit besonders markierte Assoziation ist die hat-Beziehung,
die die Hierarchie zwischen einem Ganzen und seiner Teile ausdr uckt.
Beispiel: Ein Pkw hat 34 R ader
Pkw
hat
1
3..4
Rad
Beispiel: Ein Unternehmen hat 1..* Abteilungen mit jeweils 1..* Mitarbeitern
Unternehmen
besteht aus
1
1..*
Abteilung
umfat
1
1..*
Mitarbeiter
Ein Aggregat kann (meistens zu Anfang) auch ohne Teile sein: die Multiplizit at 0 ist zul assig.
Gew ohnlich ist es jedoch Sinn eines Aggregats, Teile zu sammeln.
Bei einem Aggregat handelt das Ganze stellvertretend f ur seine Teile, d.h. es ubernimmt Opera-
tionen, die dann an die Einzelteile weiterpropagiert werden.
Beispiel: Methode berechneUmsatz() in der Klasse Unternehmen, die den Umsatz der Ab-
teilungen aufsummiert.
191
11.3.3 Komposition
Ein Sonderfall der Aggregation ist die Komposition, markiert mit .
Eine Komposition liegt dann vor, wenn das Einzelteil vom Aggregat existenzabh angig ist also
nicht ohne das Aggregat existieren kann.
Beispiel: Rechnungsposition
Eine Rechnungsposition geh ort immer zu einer Rechnung.
Rechnung
hat
1
1..*
Rechnungsposition
Beispiel: Buch
Ein Buch besteht aus Inhaltsverzeichnis, mehreren Kapiteln, Index; ein Kapitel besteht aus meh-
reren Abschnitten usw.
Buch
hat
0..*
1
hat
1
1
hat
0..*
1
Kapitel Abschnitt
hat
1
Inhaltsverzeichnis
Index
Absatz
hat
1
1
0..*
0..*
0..*
0..*
192
Beispiel: Kreiseck
Ein
Kreiseck besteht aus einem ubereinander gelegten Quadrat und einem Kreis:
Modellierung als Klasse SquareCircle, die sowohl einen Kreis als auch ein Quadrat enth alt:
Shape
-position: Point = (10, 10)
+area(): double
+draw()
+set_position(position:Point)
+get_position(): Point
Circle
-radius: double = 1 {radius > 0}
+area(): double
+draw()
+set_radius(radius:double)
+get_radius(): double
Rectangle
-a: double = 10 {a > 0}
-b: double = 10 {b > 0}
+area(): double
+draw()
+set_a(length:double)
+set_b(length:double)
+get_a(): double
+get_b(): double
SquareCircle
{2 * k.radius = r.a = r.b}
+set_a(length:double)
+resize(factor:double)
Erg anzungen
Ein Einzelteil kann immer nur von einem Aggregat existenzabh angig sein.
Eine Klasse kann auch als Komposition aller ihrer Attribute aufgefat werden.
In vielen Programmiersprachen werden Aggregationen durch Referenzen (Zeiger auf Objekte)
realisiert, Kompositionen jedoch durch die Werte selbst.
193
11.3.4 Rollen
An jedem Ende einer Assoziation k onnen Rollennamen vergeben werden. Ein Rollenname be-
schreibt, wie das Objekt durch das in der Assoziation gegen uberliegende Objekt gesehen wird.
Beispiel (vergl. Abschnitt 11.2.5): Eine Person wird vom Arbeitgeber als Arbeitnehmer, vom
Hausarzt als Patient gesehen.
Person
+get_gesundheit()
+get_qualifikation()
Firma
Arzt
+arn: Arbeitnehmer
+Patient
Arbeitgeber
Hausarzt
<<interface>>
Arbeitnehmer
+get_qualifikation()
Zus atzlich zum Rollennamen kann der Name einer Schnittstelle angegeben werden, die von der
jeweiligen Klasse implementiert wird (hier: die Schnittstelle Arbeitnehmer zum Rollennamen
arn).
In diesem Fall wird der Umfang der Assoziation eingeschr ankt es sind nur noch die Attribu-
te/Methoden der Schnittstelle sichtbar.
In obigem Beispiel kann etwa die Firma nicht auf die Patientendaten zugreifen.
194
11.3.5 Mehrgliedrige Assoziationen
Neben Zweierbeziehungen gibt es noch mehrgliedrige Assoziationen Assoziationen, an denen
drei oder mehr Klassen beteiligt sind.
Tern are Assoziationen
Beispiel f ur eine tern are (dreigliedrige) Assoziation: Studenten h oren Vorlesungen bei Professo-
ren
Professor
+name: string
Student
+name: string
hlt
1
hrt
+1
Vorlesung
+titel: string
1..*
Mehrgliedrige Assoziationen lassen sich gew ohnlich in normale Assoziationen umformen:
Professor
+name: string
Student
+name: string
hlt
1
1..*
hrt
1..*
Vorlesung
+titel: string
1..*
1..*
195
Mehrgliedrige Assoziationen
Beispiel f ur eine viergliedrige Assoziation: Fahrg aste reservieren Pl atze f ur Abschnitte von Z ugen.
Zug
+datum:
+zugnr:
Abschnitt
+von_bahnhof:
+bis_bahnhof:
Fahrgast
+name:
+geschlecht:
Platz
+wagen_nr:
+platz_nr:
1
1..*
1
1..*
Reservierung
Auch hier gibt es eine Umformung in normale Assoziationen:
Zug
+datum:
+zugnr:
Abschnitt
+von_bahnhof:
+bis_bahnhof:
Fahrgast
+name:
+geschlecht:
Platz
+wagen_nr:
+platz_nr:
1
0..* 0..*
1..*
0..*
0..*
1
1..*
Reservierung
196
11.4 Formale Zusicherungen
Neben Attributen k onnen beliebige UML-Elemente mit Zusicherungen versehen werden. Dies
geschieht entweder frei formuliert oder mit Hilfe der UML-eigenen Object Constraint Language,
kurz OCL.
11.4.1 Beispiel: Projektleitung
Der Leiter eines Projekts rekrutiert sich aus den Reihen der Projektmitglieder.
Informale Zusicherung:
hat
Leiter
1
besteht aus
Projektmitglied
1..*
{subset}
Projekt
Mitarbeiter
Die Zusicherung ist als subset frei formuliert mit der Bedeutung projektleiter projektmitglieder.
Formale Zusicherung:
hat
Leiter
1
besteht aus
Projektmitglied
1..*
Projekt
Mitarbeiter
Projekt
self.projektmitglieder->
includes(self.projektleiter)
Der OCL-Ausdruck
self .projektmitglieder includes(self .projektleiter)
bedeutet, da die Mengenoperation includes, die auf die Menge der Projektmitglieder angewandt
wird, und der der Projektleiter als Argument ubergeben wird, den Wert true liefern mu.
197
11.4.2 Beispiel: Reservierungen
Die Anzahl der reservierten Pl atze (vergl. Abschnitt 11.3.5) mu mit der Anzahl der Fahrg aste
ubereinstimmen
Zug
+datum:
+zugnr:
Abschnitt
+von_bahnhof:
+bis_bahnhof:
Fahrgast
+name:
+geschlecht:
Platz
+wagen_nr:
+platz_nr:
1
0..* 0..*
1..*
0..*
0..*
1
1..*
Reservierung
Reservierung
self.platz->size ==
self.fahrgast->size
Die Operation size gibt die Anzahl der Elemente zur uck.
11.4.3 Weitere OCL-Beispiele
Das Gehalt des Mitarbeiters mu kleiner sein als das Gehalt des Chefs:
mitarbeiter.gehalt < chef.gehalt
Die Person mu vollj ahrig sein:
person.alter >= 18
Eine Person mu mindestens eine Anschrift haben
not person.anschriften->isEmpty oder
person.anschriften->size >= 1
Alle Fahrer eines Mietwagens m ussen alter als 21 sein
self.fahrer->forAll(f | f.alter >= 21)
Solche Zusicherungen k onnen ggf. in Zusicherungen der Programmiersprache ubersetzt werden,
die dann zur Laufzeit Verletzungen aufdecken.
198
11.5 Sequenzdiagramme
Ein Sequenzdiagramm gibt den Informationsu zwischen einzelnen Objekten wieder mit Beto-
nung des zeitlichen Ablaufs.
Objekte werden mit senkrechten Lebenslinien dargestellt; die Zeit verl auft von oben nach unten.
Der Steuerungsfokus (breiter Balken) gibt an, welches Objekt gerade aktiv ist. Ruft eine Methode
eines aktiven Objekts (indirekt) eine weitere Methode des Objekts auf, wird dies durch multiple
Balken dargestellt.
Pfeile (
...
class Rectangle
private double a;
private double b;
public double get_a()
return a;
...
201
class Circle
private double radius;
public double get_a()
return a;
...
202
11.5.2 Beispiel: Erzeugen und L oschen von Objekten
Situation: ein Benutzer m ochte in einem Hotel ein Zimmer f ur eine bestimmte Anzahl von Tagen
reservieren. Sp ater sagt er die erhaltene Reservierung ab.
hotel: Hotel
reservation:
Reservation
Benutzer
reservation(days)
[is_room] <<create>>
cancel(reservation)
Falls ein Raum fr
jeden Tag frei ist:
Reserviere den Raum
is_room := available(day)
reservation
<<destroy>>
X
loop
[for each day: days]
Zun achst pr uft das Hotel, ob es ein Zimmer gibt, das an s amtlichen Tagen frei ist. Dazu wird
uber die Tage iteriert.
die Struktur loop [...] beschreibt eine Iteration, in der Klammer steht die Abbruchbedin-
gung
Falls ein Zimmer zur Verf ugung steht, wird ein Objekt des Typs Reservation erzeugt und
zur uckgegeben.
das Erzeugen von Objekten wird mit dem Schl usselwort create gekennzeichnet
203
Ausdr ucke in [] stellen Bedingungen dar
Sp ater widerruft der Benutzer die Reservierung. Das Hotel l oscht die Reservierung.
das L oschen von Objekten wird mit dem Schl usselwort destroy gekennzeichnet
die Lebenslinie endet an diesem Punkt mit einem Kreuz
204
11.5.3 Beispiel: Darstellung von Nebenl augkeit
Zur Darstellung von Nebenl augkeit k onnen asynchrone Nachrichten verwendet werden. Diese
werden durch Pfeile mit halben K opfen dargestellt.
tutor: Tutor group: Course
administration:
Administration
room := free_room(day)
time := meeting_time()
reserve(room, day, time)
Im Beispiel m ochte ein Tutor einen Raum f ur ihre Gruppe an einem bestimmten Tag reservieren.
Dazu ben otigt sie einen Raum und eine genaue Uhrzeit. Diese Information kann sie in beliebiger
Reihenfolge erhalten, daher die Nebenl augkeit. Anschliessend wird der Raum reserviert.
205
11.6 Kommunikationsdiagramme
Kommunikationsdiagramme beschreiben ebenfalls den Informationsu zwischen einzelnen Ob-
jekten.
Im Gegensatz zu Sequenzdiagrammen betonen sie aber die Beziehungsstruktur der Objekte.
11.6.1 Beispiel: Vergr oern eines Kreisecks
Das bekannte Szenario aus Abschnitt 11.5.1 diesmal als Kommunikationsdiagramm:
r: Rechteck k: Kreis
: Kreiseck
1.1: a := get_a()
1.2.1: set_radius(a / 2)
1: resize(factor)
1.2: set_a(a)
Neues a:
a = a * factor
1.2.2: set_a(a)
1.2.3: set_b(a)
Im Kommunikationsdiagramm werden die Nachrichten durchnumeriert. Die Gliederung gibt da-
bei an, welche Objekte noch aktiv sind.
1 Nachricht ans Kreiseck: Vergr oern um factor
1.1 Kreiseck holt aktuelle Gr oe von Rechteck r
1.2 Kreiseck multipliziert seine Gr oe mit factor
1.2.1 Kreiseck setzt neue Gr oe des Kreises
1.2.2 Kreiseck setzt neue Kantenl ange des Rechtecks
1.2.3 Dito f ur zweite Kantenl ange
206
11.7 Zustandsdiagramme
Ein Zustandsdiagramm zeigt eine Folge von Zust anden, die ein Objekt im Laufe seines Lebens
einnehmen kann und aufgrund welcher Ereignisse Zustands anderungen stattnden.
Ein Zustandsdiagramm zeigt einen endlichen Automaten(vergl. Abschnitt 7.6.1).
Zustands uberg ange werden in der Form
Ereignisname[Bedingung]/Aktion
notiert. Hierbei ist
Ereignisname der Name eines Ereignisses (typischerweise ein Methodenaufruf);
Bedingung die Bedingung, unter der der Zustands ubergang stattndet (optional)
Aktion eine Aktion, die beim
Ubergang ausgef uhrt wird (optional)
Auch Zust ande k onnen mit Aktionen versehen werden: Das Ereignis entry kennzeichnet das
Erreichen eines Zustands; exit steht f ur das Verlassen eines Zustands.
11.7.1 Beispiel: Flugreservierung
Wird ein Flug eingerichtet, ist noch nichts reserviert. Die Aktion ruecksetzen() sorgt daf ur,
da die Anzahl der freien und reservierten Pl atze zur uckgesetzt wird.
reservieren()
teilweise
reserviert
stornieren()
[reserviertePlaetze == 1]
stornieren()
[reserviertePlaetze > 1]
reservieren()
[freiePlaetze > 1]
ausgebucht
reservieren()
[freiePlaetze == 1]
flug
einrichten()
stornieren()
geschlossen
schliessen()
schliessen()
flug
streichen()
Ohne
Reservierung
entry /ruecksetzen()
207
11.8 Fallstudie: Tabellenkalkulation
Eine Tabelle besteht aus mn Zellen
Zellen sind entweder leer oder haben einen Inhalt
Inhalte sind Zahlen, Texte oder Formeln
Zu einem Inhalt gibt es mehrere Formeln (die die Inhalte ansprechen)
Zu einer Formel gibt es mehrere Inhalte (die als Operanden in der Formel auftreten)
11.8.1 Objektmodell
gibWert() gibt den Wert der Zelle (des Inhalts) zur uck
belege() belegt eine Zelle (einen Inhalt) mit einem neuen Wert
benachrichtige() ruft nach einer
Anderung eines Inhalts aktualisiere() f ur alle For-
meln auf, in der der Inhalt als Operand auftritt. Diese berechnen und belegen daraufhin ihr Er-
gebnis neu.
Tabelle
hat 1
0..*
Zelle
+gibWert(): Inhalt
+belege(s:string)
Inhalt
+gibWert(): Inhalt
+belege(s:string)
-benachrichtige()
Inhalt
0..1
Zelle
1
Zahl
-wert: double
+belege(s:string)
Text
-wert: string
+belege(s:string)
Formel
+gibWert(): Inhalt
+belege(s:string)
+aktualisiere()
Operand
0..*
Ergebnis 1
1
Formel
0..*
208
11.8.2 Beispiel f ur Objektbeziehungen
Die Tabelle sei wie folgt belegt:
A1 = 1 B1 = A1 + A2
A2 = 10 B2 = B1 + A3
A3 = 100
Dann sind die Inhalte wie folgt verkn upft:
a1: Zahl
wert = 1
a2: Zahl
wert = 10
b1: Formel
b1 = a1 + a2
operand operand
b2: Formel
b2 = b1 + a3
a3: Zahl
wert = 100
operand operand
b1: Zahl
wert = 11
ergebnis
b2: Zahl
wert = 111
ergebnis
209
11.8.3 Zustandsdiagramm
Die Methode belege der Klasse Inhalt pr uft, ob sich der Wert ge andert hat. Wenn ja, be-
nachrichtigt sie mit benachrichtige() alle Formelobjekte, in denen der Inhalt als Operand
vorkommt.
konstanter Wert
vernderter Wert
belege()
[neuer Wert =
alter Wert]
benachrichtige()
11.8.4 Sequenzdiagramm
Beispiel: Die Tabelle sei belegt wie in Abschnitt 11.8.2 beschrieben; nun andern wir den Wert
der Zelle A1 von 1 auf 5.
a1: Zahl
wert = 1
a2: Zahl
wert = 10
b1: Formel
b1 = a1 + a2
b2: Formel
b2 = b1 + a3
a3: Zahl
wert = 100
Benutzer
belege("5")
b1: Zahl
wert = 11
b2: Zahl
wert = 111
aktualisiere()
gibWert()
5
gibWert()
10
belege("15")
aktualisiere()
gibWert()
100
gibWert()
10
belege("115")
Wie nde ich die Objekte? ist die schwierigste Frage der Analyse.
Es gibt keine eindeutige Antwort: Man kann ein Problem auf verschiedene Weisen objektorien-
tiert modellieren.
11.9.1 Entwurf nach Zust andigkeit
Ein verbreitetes Grundprinzip ist der Entwurf nach Zust andigkeit: Jedes Objekt ist f ur bestimmte
Aufgaben zust andig und
besitzt entweder die F ahigkeiten, die Aufgabe zu l osen,
oder es kooperiert dazu mit anderen Objekten.
Ziel ist damit das Aufnden von Objekten anhand ihrer Aufgaben in der Kooperation.
Wir gehen zun achst von einer informalen Beschreibung aus und betrachten zentrale Begriffe der
Aufgabenstellung:
Hauptworte in der Beschreibung werden zu Klassen und konkreten Objekten
Verben in der Beschreibung werden zu Diensten
entweder zu Diensten, die ein Objekt anbietet,
oder zu Aufrufen von Diensten kooperierender Objekte.
Diese Dienste kennzeichnen die Zust andigkeit und Kooperationen der einzelnen Klassen.
Die so gefundenen Klassen werden dann anhand ihrer Zust andigkeiten auf sogenannte KZK-
Karten (Klasse Zust andigkeit Kooperation) notiert:
Klassenname Zusammenarbeit mit
zust andig f ur
Die KZK-Karte gibt die Rolle wieder, die Objekte im Gesamtsystem ubernehmen sollen.
211
11.9.2 Beispiel: Rechnerversand
Student Fritz bestellt mit einem Brief bei der Firma Rechnerwelt einen Rechner. Die-
ser wird ihm nach mehreren Tagen als Paket durch die Firma Gelbe Post zugestellt.
Eine erste N aherung k onnte so aussehen:
Student Zusammenarbeit mit
zust andig f ur
bestellen Rechnerh andler
Paket annehmen Zusteller
Rechnerh andler Zusammenarbeit mit
zust andig f ur
Bestellung annehmen Student
Paket absenden Zusteller
Zusteller Zusammenarbeit mit
zust andig f ur
Paket annehmen Rechnerh andler
Paket abgeben Student
Diese erste N aherung ist jedoch noch nicht vollst andig:
Fritz tritt in seiner Rolle als Kunde auf; es kommt nicht darauf an, da er auch Student ist
(es sei denn, er bek ame Studentenrabatt). Besser w are also der Klassenname Kunde statt
Student.
Brief und Paket fehlen es handelt sich um reine Datenobjekte, die weder Zust andigkeit
noch Kooperationspartner haben.
Wir haben offengelassen, wie der Bestellbrief zum Rechnerh andler gelangt; ggf. ist hierf ur
ebenfalls ein Zusteller zust andig.
Datenu, Zustands uberg ange und Klassenhierarchien sind nicht ber ucksichtigt.
212
11.9.3
Uberarbeitung des Entwurfs (Restrukturierung)
Nachdem ein erster Grobentwurf fertiggestellt ist, sollte versucht werden, ihn anhand der folgen-
den Gesichtspunkte zu verbessern:
Herausfaktorisieren gleicher Merkmale. K onnen gemeinsame Merkmale (Attribute, Metho-
den) verschiedener Klassen miteinander in Zusammenhang gebracht werden?
Diese gemeinsamen Merkmale k onnen
in eine dritte Klasse verlagert werden, die von den bestehenden Klassen aggregiert
wird. Die bestehenden Klassen m ussen die ausgelagerten Dienste aber weiterhin an-
bieten
in eine gemeinsame Oberklasse verlagert werden. Dies ist bei gemeinsamen ist-ein-
Beziehungen sinnvoll.
Verallgemeinerung von Verhaltensweisen. K onnen Methoden mit einheitlicher Schnittstelle be-
reits auf einer abstrakten Ebene angegeben werden?
Abstrakte Klassen k onnen etwa allgemeine Methoden bereitstellen, deren Details (abge-
leitete Kernmethoden) in den konkreten Unterklassen realisiert werden.
Ersetzen einer umfangreichen Klasse durch ein Teilsystem. K onnen Klassen mit vielen Merk-
malen weiter unterteilt werden?
Evtl. Einf uhrung eines Teilsystems aus mehreren Objekten und zugeh origen Klassen
Minimierung von Objektbeziehungen. Kann man durch Umgruppierung der Klassen oder neue
Schnittstellen die Zahl der
Benutzt-Beziehungen verringern?
Auch hier unterh alt nur noch ein neu einzuf uhrendes Teilsystem Auenbeziehungen.
Wiederverwendung, Bibliotheken. Kann man bestehende Klassen wiederverwenden?
Ggf. k onnen geeignete Anpassungsklassen (Adapter) eingef uhrt werden
Generizit at. K onnen generische Klassen und Methoden eingesetzt werden?
Oder auch: k onnen Klassen und Methoden des Entwurfs generisch gestaltet werden?
Entwurfsmuster. Kann man Standard-Architekturbausteine (Kapitel 12)einsetzen?
213
11.9.4 Beispiel: Rechnerversand
Objektmodell
Anschrift: herausfaktorisiert als gemeinsame Attribute von Kunden und H andlern
Die neue Klasse Paket besteht aus Absender- und Empf angeradresse.
Bestellung: ebenfalls neu; besteht u.a. aus einer Bestelleradresse
Anschrift
-name: string
-adresse: string
Paket
Bestellung
Kunde
+annehmen(p:Paket)
+versandt(b:Bestellung)
Rechnerhndler
+annehmen(b:Bestellung)
Zusteller
-name: string
+annehmen(p:Paket)
Empfnger
Absender
Besteller
1
0..*
1
0..*
Sequenzdiagramm
k: Kunde
r: Rechnerhndler z: Zusteller
annehmen()
annehmen()
annehmen()
versandt()
empfangen()
214
11.10 Fallstudie: Geldautomat
11.10.1 Problembeschreibung
Ein Geldautomat (Scheckkartenautomat, SKA) ist eine Maschine, mit der Bankkunden Geld
von ihrem Girokonto abheben und sich uber ihren Kontostand informieren k onnen. Er besteht
aus einem Anzeigefeld, einem Scheckkartenleser, einem Geldausgabefach, einem Ziffern- und
einem Funktionsfeld.
Im Grundzustand wird eine Begr uungsnachricht
Auszahlung und
Kontostand zu w ahlen.
Andernfalls hat der Kunde noch zwei Versuche frei, die Geheimzahl korrekt einzugeben. Schl agt
auch der dritte Versuch fehl, so wird die Karte einbehalten und nur am Bankschalter zur uckge-
geben.
Mit der entsprechenden Funktionstaste kann der Kunde den Bearbeitungsvorgang ausw ahlen.
215
Soll der Kontostand angezeigt werden, erscheint zun achst die Nachricht
Bitte Karte entnehmen; die Karte wird ausgeworfen und das System geht in den Grundzustand.
F ur eine Auszahlung wird der Kunde aufgefordert, den Betrag einzugeben. Der Betrag wird mit
Zifferntasten eingegeben, jede Ziffer wird angezeigt. Die Eingabe wird mit der Taste
Betrag
best atigt. Danach erscheint eine Nachricht
Vertragspartner genannt).
Im Beispiel ergeben sich u.a. folgende Methoden:
1 Bearbeitungsvorgang: Bearbeitungsvorgang ausf uhren
2 Konto: Kontoinformation abfragen
3 Konto: Betrag abbuchen
4 Meldung: Text ausgeben
5 Formular: Text ausgeben, Eingabe liefern
6 Kartenleser: Karte einlesen, auswerfen, behalten
7 Tastenfeld: gedr uckte Taste ubermitteln
8 Anzeigenfeld: Text anzeigen
9 Ausgabefach: Geld bereitstellen
Das Benutzt-Diagramm gibt an, welche Klasse welche Methoden verwendet. Dazu werden Ver-
erbungsb aume zu Teilsystemen zusammengefat.
221
Fat man noch Konto und Bearbeitungsvorgang zum Subsystem Finanzmanager zusammen,
sowie Ger at und Dialog zu Dialogmanager, so erh alt man eine klassische Architektur, deren
Grundlage die Trennung von Benutzerschnittstelle und Kernfunktionalit at ist:
Abschlieende Grobstruktur:
Eine solche Architektur k onnte auch bei modularem Entwurf entstehen!
222
11.10.6 Zustandsdiagrammm
Das Zustandsdiagramm gibt f ur jede Klasse die m oglichen Aufrufsequenzen der Methoden an.
Dabei werden auch Aktionen des Kunden ber ucksichtigt.
Es m ussen alle denkbaren F alle ber ucksichtigt werden, insbesondere auch falsche Benutzerein-
gabe (Robustheit!)
Ubung: Geben Sie ein m oglichst vollst andiges Objektmodell des Scheckkartenautomaten an. Das
Modell soll die Assoziations- und Aggregationsbeziehungen sowie die Signaturen der ben otigten
Methoden enthalten.
223
11.11 Vom Modell zum Programm
Wie verwandelt man den Entwurf in einen Quelltext?
1. Klassen und Vererbung k onnen direkt aus dem Klassendiagramm entnommen werden. Die
Methoden(k opfe) ebenso. Zu jeder Methode mu eine vollst andige Signatur angegeben
werden.
2. Assoziationen zwischen Klassen werden durch Attribute realisiert.
Eine n : 1 oder 1 : 1 Assoziation von P nach Q wird in P durch ein Attribut q vom
Typ Q realisiert.
Eine 1 : n- bzw. n : m-Assoziation von P nach Q wird durch eine Menge qs vom
Typ set(Q) realisiert. (Implementierung als Feld, Liste. . . )
Falls Assoziationen eigene Methoden haben, mu man sie als eigene (Hilfs-) Klassen im-
plementieren.
3. F ur jede Klasse sollte eine Invariante formuliert und dokumentiert werden; f ur jede Me-
thode eine Vor- und Nachbedingung.
4. Die Methodenr umpfe werden implementiert. Dabei wird vorgegangen wie in der traditio-
nellen Programmierung.
5.
Uberpr ufung des Zustandsdiagramms: sind genau die im dynamischen Modell angegebe-
nen Aufrufsequenzen zul assig? Unzul assige Aufrufe m ussen durch Ausnahme/Fehlerbehandlung
abgefangen werden! Dazu kann es sinnvoll sein, die Vorbedingung dynamisch zu uber-
pr ufen.
6. Zum Testen werden die ublichen Verfahren angewendet (siehe Kapitel 17).
Moderne Programmierumgebungen erzeugen aus einem Entwurf automatisch Codeschablonen:
1. Man entwirft ein System mit allen Klassen und Attributen.
2. Die Programmierumgebung erzeugt entsprechende Codeschablonen.
3. Nun m ussen
ikoniziert)
Ein DialogWindow ist ein tempor ares Fenster, das auf einem Besitzer-Fenster liegt.
Diese Fenstertypen k onnen in einer Window-Klassenhierarchie angeordnet werden:
238
Diese Fenstertypen sind nicht die einzige m ogliche Variation.
Lexi k onnte auf mehreren verschiedenen Fenstersystemen laufen etwa Windows, Macintosh,
und das X Window System.
Es gibt drei Alternativen, um diese zus atzliche Variation zu modellieren:
Neue Unterklassen. F uhre neue Unterklassen ein, die die Variation einkapseln, wie PMIcon-
Window, MacIconWindow, XIconWindow.
ApplicationWindow
MacApplWindow
PMApplWindow
XApplWindow
Window
IconWindow
MacIconWindow
PMIconWindow
XIconWindow
DialogWindow
MacDialogWindow
PMDialogWindow
XDialogWindow
Gemeinsamer Code f ur alle Fenstersysteme ist nicht in gemeinsamer Oberklasse
Mit n Fenstertypen und m Fenstersystemen erhalten wir n m neue Klassen
Mehrfach-Vererbung. Erzeuge zwei Hierarchien f ur den Fenstertyp (Window) und das Fen-
stersystem (WindowImp) und benutze mehrfache Vererbung, um neue zusammengesetzte
Klassen zu erzeugen: Jede Klasse erbt einen Fenstertyp und eine Implementierung.
Window
IconWindow DialogWindow MacWindowImp PMWindowImp XWindowImp ApplicationWindow
WindowImp
MacApplWindow MacIconWindow MacDialogWindow etc.
Wir bekommen nach wie vor n m neue Klassen.
239
Dynamische Kopplung. Wir koppeln Fenstertyp und Fenstersystem dynamisch mittels eines
implementation-Verweises; jedes Window-Objekt verweist auf eine bestimmte WindowImp-
Implementierung.
Dies ist eine Auspr agung des Bridge-Musters.
240
Das Bridge-Muster
Problem
Benutze das Bridge-Muster, wenn
Du eine Abstraktion von ihrer Implementierung entkoppeln willst (etwa wenn die Imple-
mentierung zur Laufzeit ausgew ahlt wird)
sowohl die Abstraction als auch die Implementierung erweiterbar sein sollen.
Struktur
Teilnehmer
Abstraction (Window)
deniert die Schnittstelle der Abstraktion
unterh alt einen Verweis zu einem Objekt vom Typ Implementor
RenedAbstraction (IconWindow)
erweitert die Schnittstelle von Abstraction
Implementor (WindowImp)
deniert die Schnittstelle f ur Implementierungs-Klassen (gew ohnlich primitive Ope-
rationen; die h oheren Operationen sind in Abstraction realisiert)
ConcreteImplementor (XWindowImp, PMWindowImp)
realisiert die Implementor-Schnittstelle und deniert ihre konkrete Implementierung
241
Folgen
Das Bridge-Muster
entkoppelt Schnittstelle und Implementierung:
Eine Abstraktion ist nicht fest an eine Schnittstelle gebunden
Die Implementierung kann zur Laufzeit konguriert (und sogar ge andert) werden
Wir unterst utzen eine bessere Gesamt-Struktur des Systems
verbessert die Erweiterbarkeit
versteckt Implementierungs-Details vor dem Benutzer
Weitere Einsatzgebiete: Darstellung von Bildern (z.B. JPEG/GIF/TIFF), String-Handles
242
12.7 Benutzer-Aktionen das Command-Muster
Lexis Funktionalit at ist auf zahlreichen Wegen verf ugbar: Man kann die WYSIWIG-Darstellung
manipulieren (Text eingeben und andern, Cursor bewegen, Text ausw ahlen) und man kann wei-
tere Aktionen uber Men us, Schalt achen und Abk urzungs-Tastendr ucke ausw ahlen.
Wir m ochten eine bestimmte Aktion nicht mit einer bestimmten Benutzerschnittstelle koppeln,
weil
es mehrere Benutzungsschnittstellen f ur eine Aktion geben kann (man kann die Seite mit
einer Schalt ache, einem Men ueintrag oder einem Tastendruck wechseln)
wir wom oglich in Zukunft die Schnittstelle andern wollen.
Umdie Sache weiter zu verkomplizieren, m ochten wir auch Aktionen r uckg angig machen k onnen
(undo) und r uckg angig gemachte Aktionen wiederholen k onnen (redo).
Wir m ochten mehrere Aktionen r uckg angig machen k onnen, und wir m ochten Makros (Kom-
mandofolgen) aufnehmen und abspielen k onnen.
Wir denieren deshalb eine Command-Klassenhierarchie, die Benutzer-Aktionen einkapselt.
243
Spezische Glyphen k onnen mit Kommandos verkn upft werden; bei Aktivierung der Glyphen
werden die Kommandos ausgef uhrt.
Dies ist eine Auspr agung des Command-Musters.
244
Das Command-Muster
Problem
Benutze das Command-Muster wenn Du
Objekte parametrisieren willst mit der auszuf uhrenden Aktion
Kommandos zu unterschiedlichen Zeiten ausl osen, einreihen und ausf uhren m ochtest
die R ucknahme von Kommandos unterst utzen m ochtest (siehe unten)
Anderungen protokollieren m ochtest, so da Kommandos nach einem System-Absturz
wiederholt werden k onnen.
Struktur
245
Teilnehmer
Command (Kommando)
deniert eine Schnittstelle, um eine Aktion auszuf uhren
ConcreteCommand (PasteCommand, OpenCommand)
deniert eine Verkn upfung zwischen einem Empf anger-Objekt und einer Aktion
implementiert Execute(), indem es die passenden Methoden auf Receiver aufruft
Client (Benutzer; Application)
erzeugt ein ConcreteCommand-Objekt und setzt seinen Empf anger
Invoker (Aufrufer; MenuItem)
fordert das Kommando auf, seine Aktion auszuf uhren
Receiver (Empf anger; Document, Application)
wei, wie die Methoden ausgef uhrt werden k onnen, die mit einer Aktion verbunden
sind. Jede Klasse kann Empf anger sein.
Folgen
Das Command-Muster
entkoppelt das Objekt, das die Aktion ausl ost, von dem Objekt, das wei, wie die Aktion
ausgef uhrt werden kann
realisiert Kommando als rst-class-Objekte, die wie jedes andere Objekt gehandhabt und
erweitert werden k onnen
erm oglicht es, Kommandos aus anderen Kommandos zusammenzusetzen (siehe unten)
macht es leicht, neue Kommandos hinzuzuf ugen, da existierende Klassen nicht ge andert
werden m ussen.
246
12.7.1 Kommandos r uckg angig machen
Mittels einer Kommando-Historie kann man leicht r ucknehmbare Kommandos gestalten. Eine
Kommando-Historie sieht so aus:
present
past commands
Um das letzte Kommando r uckg angig zu machen, rufen wir Unexecute() auf dem letzten
Kommando auf. Das heit, da jedes Kommando genug Zustandsinformationen halten mu, um
sich selbst r uckg angig zu machen.
present
Unexecute()
Nach dem R ucknehmen bewegen wir die
Die besten Entw urfe werden zahlreiche Entwurfsmuster benutzen, die sich gegenseitig
erg anzen und durchdringen, um ein gr oeres Ganzes zu schaffen.
254
Kapitel 13
Software-Architektur
Nachdem wir in Kapitel 12 Muster auf der Ebene von Klassen und Objekten kennengelernt ha-
ben, besch aftigen wir uns nun mit typischen Mustern auf einer h oheren Ebene: Muster, die die
gesamte Architektur eines Systems beschreiben.
1
Wir betrachten die folgenden klassischen Architekturmuster:
Model-View-Controller
Layers
Pipes and Filters
Broker
. . . sowie einige Anti-Muster, die nicht auftreten sollten.
1
nach Buschmann et al.: Pattern-oriented software architecture. John Wiley & Sons, 1996.
255
13.1 Interaktive Systeme: Model-View-Controller
Das Model-View-Controller-Muster ist eins der bekanntesten und verbreitetsten Muster f ur die
Architektur interaktiver Systeme.
13.1.1 Beispiel: Wahlabend
Wir betrachten ein Informationssystem f ur Wahlen, das verschiedene Sichten auf Hochrechnun-
gen und Wahlergebnisse bietet.
Uber eine Spreadsheet-Schnittstelle k onnen Benutzer aktuelle
Ergebnisse eintragen.
CDU:
SPD:
FDP:
GRUENE:
PDS:
Andere:
41%
38%
8%
6%
5%
2%
CDU
SPD
FDP
GRUENE
PDS
Andere
41
38
8
6
5
2
13.1.2 Problem
Benutzerschnittstellen sind besonders h aug von
Anderungen betroffen.
Wie kann ich dieselbe Information auf verschiedene Weise darstellen?
Wie kann ich sicherstellen, da
Anderungen an den Daten sofort in allen Darstellungen
sichtbar werden?
Wie kann ich die Benutzerschnittstelle andern (wom oglich zur Laufzeit)?
Wie kann ich verschiedene Benutzerschnittstellen unterst utzen, ohne den Kern der An-
wendung zu ver andern?
256
13.1.3 L osung
Das Model-View-Controller-Muster trennt eine Anwendung in drei Teile:
Das Modell (Model) ist f ur die Verarbeitung zust andig,
Die Sicht (View) k ummert sich um die Ausgabe
Die Kontrolle (Controller) k ummert sich um die Eingabe.
Schema
View
Model
event
modify
modify
update
get
data
Controller
Ablauf
Die Kontrolle verarbeitet Eingaben und andert je nach Eingabe Modell oder Sicht.
Wurde das Modell ge andert, benachrichtigt dieses die Sicht (update).
Die Sicht ruft die aktuellen Daten des Modells ab und aktualisiert sich.
257
Klassendiagramm
Jede Sicht implementiert ein Interface Observer, damit sich beliebige Sichten beim Modell regi-
strieren lassen k onnen.
Jede Kontrolle ist genau einer Sicht zugeordnet.
Model
+coreData
+attach(Observer)
+detach(Observer)
+notify()
+getData()
+service()
View
+initialize(Model)
+makeController()
+activate()
+display()
+update()
Controller
+initialize(Model,View)
+handleEvent()
Observer
+update()
observers
0..*
1
1 0..n
Observer
registrieren
Observer
benachrichtigen
Darstellung
aktualisieren
1
In einigen Programmiersprachen oder Architekturen kann es notwendig sein, dass das Modell
bei einer
Anderung auch die Kontrolle benachrichtigt.
L osung: Kontrollen implementieren ebenfalls Interface Observer und registrieren sich beim Mo-
dell.
258
Multiple Darstellungen
Bei jedem Modell k onnen sich mehrere Sichten registrieren. H aug wird auch von Beobachtern
(Observer) des Modells gesprochen.
m: Model
spd = 45
cdu = 41 ...
pie: View bar: View c: Controller sheet: View
Bei jeder
Anderung des Modell-Zustands werden die registrierten Beobachter benachrichtigt;
sie bringen sich dann auf den neuesten Stand.
259
Teilnehmer
Das Modell (model) verkapselt Kerndaten und Funktionalit at. Das Modell ist unabh angig von
einer bestimmten Darstellung der Ausgabe oder einem bestimmten Verhalten der Eingabe.
Model Zusammenarbeit mit
zust andig f ur
Kernfunktionalit at der Anwendung
Abh angige Sichten und Kontrollen
registrieren
Registrierte Komponenten bei
Daten anderung benachrichtigen
View, Controller
Die Sicht (view) zeigt dem Benutzer Informationen an. Es kann mehrere Sichten pro Modell
geben.
View Zusammenarbeit mit
zust andig f ur
Dem Anwender Information anzeigen
Ggf. zugeordnete Kontrolle erzeugen
Liest Daten vom Modell
Controller, Model
Die Kontrolle (controller) verarbeitet Eingaben und ruft passendeDienste der zugeordeten Sicht
oder des Modells auf. Jede Kontrolle ist einer Sicht zugeordnet; es kann mehrere Kontrol-
len pro Modell geben.
Controller Zusammenarbeit mit
zust andig f ur
Benutzereingaben annehmen
Eingaben auf Dienstanforderungen
abbilden (Anzeigedienste der Sicht
oder Dienste des Modells)
View, Model
260
Dynamisches Verhalten
Beispiel:
1. Ein Controller erh alt eine Eingabe (handleEvent) und andert das Modell (service).
2. Das Modell benachrichtigt (update) die registrierten Beobachter.
3. Jeder Beobachter erfragt daraufhin vom Modell den aktuellen Zustand (getData)
4. und bringt sich selbst auf den neuesten Stand (display).
c :Controller
m: Model v: View
handleEvent()
service()
display()
getData()
update()
notify()
261
Beispiel in Java
Das Model verwaltet eine von aussen abfragbare und ver anderbare Zahl. Mehrere Beobachter
k onnen sich registrieren. Wird die Zahl ver andert, benachrichtigt das Modell s amtliche regi-
strierte Beobachter.
class Model
private int value;
private List<Observer> observer;
public void attach(Observer o) ...
public void detach(Observer o) ...
private void notify()
for (Observer o : observer)
o.update();
262
Observer ist ein Interface, das multiple Beobachter erm oglicht.
interface Observer
void update();
Die ButtonView erm oglicht mittels zweier Buttons, den Wert des Modells zu inkrementieren
oder zu dekrementieren. Sie implementiert das Observer-Interface.
Wenn die Methode update() aufgerufen wird, ruft die ButtonView den aktuellen Wert des Mo-
dells ab und zeichnet sich neu.
F ur die Buttons wird je ein Event-Listener generiert. Diese Event-Listener bilden den Controller.
class ButtonView implements Observer
private Model m;
private JButton up;
private JButton down;
public ButtonView(Model m)
...
createListeners();
...
263
Der Controller f ur die ButtonView besteht aus dem UpListener und dem DownListener. Sie wer-
ten ein erhaltenes Event (zB. Mausklick) aus und dekrementieren bzw. inkrementieren den Wert
des Modells.
class UpListener implements ActionListener
private Model m;
private View v;
public UpListener(Model m, View v) ...
public void actionPerformed(ActionEvent e)
...
m.setValue(oldValue +1);
Dem Programm k onnten noch weitere Views hinzugef ugt werden, etwa eine View mit einem
Slider zum Einstellen des Wertes.
264
Klassendiagramm
Das Klassendiagramm weicht vom vorhergehenden etwas ab: mehrere voneinander unabh angige
Klassen bilden den Controller.
Model
-value
+attach(Observer)
+detach(Observer)
+notify()
+getValue()
+setValue()
ButtonView
+ButtonView(Model)
+update()
-createListeners()
-display()
UpListener
+UpListener(Model,View)
+actionPerformed(ActionEvent)
Observer
+update()
observers
0..*
1
1 1
DownListener
+DownListener(Model,View)
+actionPerformed(ActionEvent)
1 1
1
1
265
13.1.4 Folgen des Model-View-Controller-Musters
Das Model-View-Controller-Muster hat folgende Vor- und Nachteile:
Vorteile
Mehrere Sichten desselben Modells
Synchrone Sichten
Ansteckbare Sichten und Kontrollen
Nachteile
Erh ohte Komplexit at
Starke Kopplung zwischen Modell und Sicht
Starke Kopplung zwischen Modell und Kontrollen (kann mit Command-Muster umgangen
werden)
MVC-Muster wird ggf. bereits von der GUI-Bibliothek realisiert
Bekannte Einsatzgebiete: Smalltalk, Microsoft Foundation Classes
266
13.2 Schichten und Abstraktionen: Layers
Das Layers-Muster trennt eine Architektur in verschiedene Schichten, von denen jede eine Un-
teraufgabe auf einer bestimmten Abstraktionsebene realisiert.
13.2.1 Beispiel: ISO/OSI-Referenzmodell
Netzwerk-Protokolle sind wahrscheinlich die bekanntesten Beispiele f ur geschichtete Architek-
turen. p Das ISO/OSI-Referenzmodell teilt Netzwerk-Protokolle in 7 Schichten auf, von denen
jede Schicht f ur eine bestimmte Aufgabe zust andig ist:
Application
Presentation
Session
Transport
Network
Data Link
Physical
Layer 7
Layer 6
Layer 5
Layer 4
Layer 3
Layer 2
Layer 1
Provides miscellaneous protocols
for common activities
Structures information
and attaches semantics
Provides dialog control and
synchronization facilities
Breaks messages into packets
and guarantees delivery
Selects a route
from sender to receiver
Detects and corrects errors
in bit sequences
Transmits bits: velocity,
bit-code, connection, etc.
267
13.2.2 Problem
Aufgabe: Ein System bauen, das
Aktivit aten auf niederer Ebene wie Hardware-Ansteuerung, Sensoren, Bitverarbeitung so-
wie
Aktivit aten auf hoher Ebene wie Planung, Strategien und Anwenderfunktionalit at
vereinigt, wobei die Aktivit aten auf hoher Ebene durch Aktivit aten der niederen Ebenen realisiert
werden.
Dabei sollen folgende Ziele ber ucksichtigt werden:
Anderungen am Quellcode sollten m oglichst wenige Ebenen betreffen
Schnittstellen sollten stabil (und m oglicherweisestandardisiert) sein
Teile (= Ebenen) sollten austauschbar sein
Jede Ebene soll separat realisierbar sein
13.2.3 L osung
Das Layers-Muster gliedert ein System in zahlreiche Schichten.
Struktur
Jede Schicht sch utzt die unteren Schichten vor direktem Zugriff durch h ohere Schichten.
Client Layer N
Layer N-1
Layer 1
uses
268
Teilnehmer
Schicht j Zusammenarbeit mit
zust andig f ur
Stellt Dienste bereit f ur Schicht j + 1.
Delegiert Aufgaben an Schicht j1.
Schicht j1
Dynamisches Verhalten
Es gibt verschiedene weitverbreitete Szenarien:
Top-Down Anforderung Eine Anforderung des Benutzers wird von der obersten Schicht ent-
gegengenommen; diese resultiert in Anforderungen der unteren Schichten bis hinunter auf
die unterste Ebene. Ggf. werden die Ergebnisse der unteren Schichten wieder nach oben
weitergeleitet, bis das letzte Ergebnis an den Benutzer zur uckgegeben wird.
Meist bewirkt eine Anforderung auf einer h oheren Schicht zahlreiche Anforderungen auf
einer niederen Schicht.
Bottom-Up Anforderung Hier empf angt die unterste Schicht ein Signal, das an die oberen
Schichten weitergeleitet wird; schlielich benachrichtigt die oberste Schicht den Benut-
zer.
Auch hier k onnen mehrere Signale auf der untersten Schicht zu einer einzigen Nachricht
auf oberen Schichten zusammengefat werden.
Protokollstack In diesem Szenario kommunizieren zwei n-Schichten-Stacks miteinander. Eine
Anforderung wandert durch den ersten Stack hinunter, wird ubertragen und schlielich als
Signal vom zweiten Stack empfangen. Jede Schicht verwaltet dabei ihr eigenes Protokoll.
Beispiel TCP/IP-Stack:
269
HTTP
TCP
IP
Ethernet
HTTP
TCP
IP
Ethernet
HTTP-Protokoll
TCP-Protokoll
IP-Protokoll
Ethernet-Protokoll
Physikalische Verbindung
Anforderung
Benachrichtigung
Ubermittelt Daten.
Puffert Daten.
Synchronisiert aktive Nachbarn.
Datenquelle, Filter, Datensenke
Eine Pipe kann auch durch Aufruf implizit realisiert werden etwa, indem der erste Filter
Dienste des zweiten Filter aufruft. Dies erschwert aber die freie Kombination von Filtern.
Datenquelle, Datensenke Diese Komponenten sind die Endst ucke der Pipeline und somit die
Verbindung zur Auenwelt.
Datenquelle/-senke Zusammenarbeit mit
zust andig f ur
Ubermittelt Daten an/aus Pipeline.
Pipe
Eine Datenquelle kann entweder aktiv sein (dann reicht sie von sich aus Daten in die Pipe-
line) oder passiv (dann wartet sie, bis der n achste Filter Daten anfordert).
Analog kann die Datensenke aktiv Daten anfordern oder passiv auf Daten warten.
274
Dynamisches Verhalten
Zwei aktive Filter sind durch eine Pipe verbunden; beide Filter arbeiten parallel.
Die Pipe puffert Ein- und Ausgabedaten; Zur Vereinfachung nehmen wir an, da die Pipe genau
ein Datenelement puffern kann.
1. Zun achst versucht Filter f2, aus der Pipe zu lesen (read); er mu warten.
2. Filter f1 liest (read) und verarbeitet (f1) Daten und schreibt (write) sie in die Pipe.
3. Filter f2 kann die Daten nun lesen, verarbeiten (f2) und sie in die Datensenke (write)
schreiben.
4. Filter f1 hat gleichzeitig ein weiteres Datenelement verarbeitet (f1); beim Schreiben
(write) mu er jedoch warten,. . .
5. . . . bis Filter f2 das Element gelesen hat (read).
read()
read()
write()
read()
read()
f1: Filter
p: Pipe
f2: Filter s: Datensenke
q: Datenquelle
f1()
write()
f2()
f1()
write()
275
13.3.4 Folgen des Pipes and Filters-Musters
Das Pipes and Filters-Muster hat folgende Vor- und Nachteile:
Vorteile
Kein Speichern von Zwischenergebnissen (z.B. in Dateien) notwendig
Flexibilit at durch Austauschen von Filtern
Rekombination von Filtern (z.B. in UNIX)
Filter k onnen als Prototypen erstellt werden
Parallel-Verarbeitung m oglich
Nachteile
Gemeinsamer Zustand (z.B. Symboltabelle in Compilern) ist teuer und unexibel.
Efzienzsteigerung durch Parallelisierung oft nicht m oglich (z.B. da Filter aufeinander
warten oder nur ein Prozessor arbeitet)
Overhead durch Datentransformation (z.B. UNIX: Alle Daten m ussen in/aus Text konver-
tiert werden)
Fehlerbehandlung ist schwer zu realisieren
Bekannte Einsatzgebiete: UNIX (Pionier)
276
13.4 Vermitteln von Ressourcen: Broker
13.4.1 Beispiel: Rechenzeit verteilen
Moderne Arbeitsplatzrechner verbringen einen Groteil ihrer Rechenzeit damit, auf Eingaben
des Benutzers zu warten.
Sie m ochten ein System bauen, in dem diese Rechenzeit anderen Anwendern zur Verf ugung
gestellt werden kann etwa, um gemeinsam rechenintensive Probleme zu l osen.
Clients Servers
Broker
Ihr System soll
zwischen Anbietern (Servern) und Anwendern (Clients) von Rechenzeit vermitteln
transparent arbeiten: Anwender m ussen nicht wissen, wo ihre Berechnungen ausgef uhrt
werden
dynamisch arbeiten: Zur Laufzeit k onnen jederzeit Anbieter und Anwender hinzukommen
oder wegfallen.
13.4.2 Problem
Ein komplexes Software-System soll als Menge von entkoppelten, zusammenarbeitenden Kom-
ponenten realisiert werden (und nicht als eine monolithische Anwendung).
Die Komponenten sollen verteilt sein; dies soll jedoch m oglichst transparent gestaltet werden.
277
Zur Laufzeit k onnen neue Komponenten hinzukommen oder wegfallen.
13.4.3 L osung
Ein Broker (Vermittler) vermittelt zwischen Dienste-Anbietern (Server) und Dienste-Anwendern
(clients). Dienste-Anbieter melden sich beim Broker an und machen ihre Dienste f ur Anwender
verf ugbar. Anwender senden Dienste-Anforderungen an den Broker, der sie an einen geeigneten
Anbieter weiterleitet.
Zu den Aufgaben des Brokers geh ort es,
den passenden Anbieter zu nden
Anfragen des Anwenders an den passenden Anbieter weiterzuleiten
die Antwort des Anbieters an den Anwender zur uckzusenden
Struktur
Broker
+main_event_loop()
+update_repository()
+register_service()
+acknowledgment()
+find_server()
+find_client()
+forward_request()
+forward_response()
Client-side Proxy
+pack_data()
+unpack_data()
+send_request()
+return()
Server-side Proxy
+pack_data()
+unpack_data()
+call_service()
+send_response()
Client
+call_server()
+start_task()
+use_Broker_API()
Server
+Initialize()
+enter_main_loop()
+run_service()
+use_Broker_API()
0..*
1
0..*
1
0..*
1
0..*
1
uses
API
uses
API
278
Teilnehmer
Server Der Server bietet Dienste an.
Server Zusammenarbeit mit
zust andig f ur
Implementiert Dienste
Meldet sich beim lokalen Broker an
Kommuniziert mit Client durch
Server-side Proxy
Server-side Proxy, Broker
Client Der Client macht die Dienste dem Benutzer zug anglich.
Client Zusammenarbeit mit
zust andig f ur
Realisiert Funktionalit at f ur Benutzer
Sendet Anfragen an Server mittels
Client-side Proxy
Client-side Proxy, Broker
Proxies Ein Proxy vermittelt zwischen Client (bzw. Server) und dem Broker. Insbesondere kap-
selt der Proxy die Kommunikation zum und vom Broker ein (einschlielich Netzzugriffen
und Aufbereiten von Daten).
Client-side Proxy Zusammenarbeit mit
zust andig f ur
Kapselt system-spezische
Funktionalit at ein
Vermittelt zwischen Client und Broker
Client, Broker
279
Server-side Proxy Zusammenarbeit mit
zust andig f ur
Fordert Dienste des Servers an
Kapselt system-spezische
Funktionalit at ein
Vermittelt zwischen Server und Broker
Server, Broker
Dynamisches Verhalten 1: Anmelden eines Servers
Szenario:
1. Ein neuer Server meldet seine Dienste beim Broker an (register service).
2. Der Broker bringt seine Server-Liste auf den neuesten Stand (update repository) und
best atigt dem Server die Registrierung (acknowledgment).
280
s: Server b: Broker
initialize()
register_service()
acknowledgment
enter_main_loop()
start main_event_loop
update_repository()
Dynamisches Verhalten 2: Anfrage uber Broker
Szenario:
1. Ein Client richtet eine Anfrage an einen Broker (call server, send request).
2. Die Anfrage wird uber einen Proxy geleitet, der die Daten zum Broker sendet (pack data,
forward request)
3. Der Broker ndet einen passenden Server (find server) und ruft dessen Dienste uber
dessen Proxy auf (call service).
4. Der Server-Proxy ruft den Dienst des Servers auf (run service).
5. Schlielich wird das Ergebnis an den Client zur uckgesandt (forward response, return).
281
run_service()
cp: Client-side Proxy
b: Broker
sp: Server-side Proxy s: Server
c: Client
pack_data()
forward_request()
unpack_data()
forward_response()
call_server()
send_request()
find_server()
call_service()
pack_data()
find_client()
return()
unpack_data()
282
13.4.4 Folgen des Broker-Musters
Das Broker-Muster hat folgende Vor- und Nachteile:
Vorteile
Transparente verteilte Dienste
Anderbarkeit und Erweiterbarkeit von Komponenten
Interoperabilit at zwischen verschiedenen Systemen
Wiederverwendbarkeit von Diensten
Nachteile
Efzienz beschr ankt durch Indirektion und Kommunikation
Test und Fehlersuche im Gesamt-System sind schwierig (andererseits kann eine neue An-
wendung auf bew ahrten Diensten aufsetzen)
Bekannte Einsatzgebiete:
Common Object Request Broker Architecture (CORBA)
Microsoft .NET
. . . und nat urlich das WWW, das gr ote Broker-System der Welt.
283
13.5 Anti-Muster
2
Treten die folgenden Muster in der Software-Entwicklung auf, ist Alarm angesagt.
13.5.1 The Blob
Main Controller Class
-DataListPoiner
-Status
-Mode
-User
-Group
-DateTime
-ACL
-ModuleButton1
-ModuleButton2
-ModuleButton3
-Iterator1
-Iterator2
-Console
-etc....
+Start()
+Stop()
+Initialize()
+SetMode()
+Login()
+SetStatus()
+BeginReviewA()
+RefreshConsole()
+Load()
+DoThis()
+DoThat()
+DoTheOther()
+etc...()
Records
Data1
CurFmt
Figures
ErrorSet
Users
Image1
-PosX
-PosY
-LocPtr
-Buffer
+...()
Image2
-PosX
-PosY
-LocPtr
-Buffer
+...()
Image3
-PosX
-PosY
-LocPtr
-Buffer
+...()
Table1
-Value
-Rows
-Cols
-Buffer
+...()
Symptome
Eine Klasse mit einer hohen Zahl an Attributen oder Operationen.
Zusammenstellung unabh angiger Attribute oder Operationen (schwache Koh asion).
Eine Kontroll-Klasse assoziiert mit trivialen Daten-Klassen.
Abwesenheit von objektorientiertem Design.
Die Blob-Klasse ist nicht wiederverwendbar und kann nicht getestet werden.
2
Nach Brown et al., AntiPatternsRefactoring Software, Architectures, and Projects in Crisis; John Wiley &
Sons, 1998
284
Zitat
Diese Klasse ist das Herz unserer Architektur.
13.5.2 Stovepipe System
Symptome
Architektur-Dokumentation stimmt nicht mit der Implementation uberein.
Gesamtsystem ist anf allig gegen uber
Anderungen, implizite Abh angigkeiten werden uber-
sehen.
Wiederverwendung einzelner Teile ist nicht m oglich.
13.5.3 Weitere AntiPatterns
The Blob.
Ein Objekt (
Blob) enth alt den Groteil der Verantwortlichkeiten, w ahrend die meisten anderen
Objekte nur elementare Daten speichern oder elementare Dienste anbieten.
L osung: Code neu strukturieren. (Kapitel 15)
285
The Golden Hammer.
Ein bekanntes Verfahren (
Hast Du einen Hammer, sieht jedes Problem wie ein Nagel aus.)
L osung: Ausbildung verbessern.
Cut-and-Paste Programming.
Code wird an zahlreichen Stellen wiederverwendet, indem er kopiert und ver andert wird. Dies
sorgt f ur ein Wartungsproblem.
L osung: Black-Box-Wiederverwendung, Ausfaktorisieren von Gemeinsamkeiten.
Spaghetti Code.
Der Code ist weitgehend unstrukturiert; keine Objektorientierung oder Modularisierung; un-
durchsichtiger Kontrollu.
L osung: Vorbeugen Erst entwerfen, dann codieren. Existierenden Spaghetti-Code neu struktu-
rieren (Kapitel 15)
Vendor Lock-In.
Ein System ist weitgehend abh angig von einer propriet aren Architektur oder propriet aren Daten-
formaten.
L osung: Portabilit at erh ohen, Abstraktionen einf uhren.
Design by Committee.
Das typische Anti-Muster von Standardisierungsgremien, die dazu neigen, es jedem Teilnehmer
recht zu machen und uberm aig komplexe und ambivalente Entw urfe abzuliefern (
Ein Kamel
ist ein Pferd, das von einem Komitee entworfen wurde). Bekannte Beispiele: SQL und CORBA.
L osung: Gruppendynamik und Treffen verbessern. (vergl. Kapitel 18)
Reinvent the Wheel.
Da es an Wissen uber vorhandene Produkte und L osungen fehlt (auch innerhalb einer Firma),
wird das Rad stets neu erfunden erh ohte Entwicklungskosten und Terminprobleme.
286
L osung: Wissensmanagement verbessern.
Weitere Anti-Muster: Lava Flow (schnell wechselnder Entwurf), Boat Anchor (Komponente oh-
ne erkennbaren Nutzen), Dead End (eingekaufte Komponente, die nicht mehr unterst utzt wird),
Swiss Army Knife (Komponente, die vorgibt, alles tun zu k onnen). . .
287
Kapitel 14
Model-Driven Architecture
Viele Software-Firmen entwickeln wiederholt ahnliche Softwaresysteme.
Wiederkehrende Implementierung derselben Klassen, Module oder Funktionen.
Hoher Anteil daran: zu implementierende Anbindungen an die verwendete Plattform.
Struktureller Code, der runterprogrammiert werden muss und fehleranf allig ist.
Ein anderes h auges Problem: ein System wurde f ur eine bestimmte Plattform entwickelt, die
nach einiger Zeit uberholt ist.
Transfer auf eine andere Plattform n otig; das kann aber sehr teuer oder gar so gut wie
unm oglich sein.
Idee: Systeme nur noch zu modellieren und Code automatisch aus dem Modell zu generieren.
Identische Aufgaben werden nur noch einmal im Generierungswerkzeug deniert; aus dem
Modell kann Code f ur verschiedene Plattformen erzeugt werden.
Code besitzt eine gleichbleibende Qualit at.
Entwurf konzentriert sich nur noch auf Anwendungslogik
Ein erster Ansatz: Ein Modell erstellen und daraus direkt den Code erzeugen.
Dieser Schritt ist zu gross, da das Modell allumfassend sein m usste. Der Implementie-
rungsaufwand w urde sich nur in die Entwicklung des Modells verlagern.
Ein verbesserter Ansatz: Aus einem initialen Modell zun achst automatisch weitere, n aher an
der Implementierung liegende Modelle erzeugen.
Hier kann das initiale Modell abstrakter gehalten werden.
288
14.1 MDA
Model-Driven Architecture (MDA) ist ein Projekt der Object Modeling Group (OMG).
Ziel: Modellierung der Architektur des zu implementierenden Systems vollst andig unabh angig
von Plattform und Sprache zu machen und aus dem Modell automatisch Code zu generieren.
Bei MDA handelt es sich sehr vereinfacht betrachtet um ein dreistuges Verfahren:
Zum achst wird ein plattformunabh angiges Modell des Systems erstellt (Platform-Independent
Model, PIM), das von Plattform und Sprache abstrahiert. Es umf asst nur die Anwendungs-
logik.
Das PIM wird in ein plattformspezisches Modell (Platform-Specic Model, PSM) trans-
formiert. Dieses abstrahiert von der Sprache und beinhaltet Information dar uber, wie die
Plattform verwendet wird.
Aus dem PSM wird schliesslich der Code erzeugt.
PIM
PSM
Code
Transformation
Transformation
289
H aug erstellt eine Transformation nur f ur einen Teil des PIM ein plattformspezisches Modell.
resultierendes PSM dient als PIM f ur weitere Transformationen
So kann eine ganze Kette von Transformationen n otig sein, bis schliesslich der Code generiert
wird.
Dieses Verfahren bietet hohe Flexibilit at: F ur verschiedene Plattformen k onnen verschiedene
PSM erstellt, f ur verschiedene Zielsprachen entsprechender Code generiert werden.
PIM
PSM 1
Transformationen
Transformationen
PSM 2
Pascal
Java C++
Vision bei MDA: Transformationen automatisch ausf uhren zu lassen.
Verwendung von Transformationswerkzeugen, die mit passenden Transformationsdenitio-
nen gef uttert werden
Entwicklung eines Systems ndet nur noch auf der Ebene der PIM statt und konzentriert sich
nur noch auf die Anwendungslogik
290
14.2 Transformationen
Transformationen bilden Strukturen eines PIM auf Strukturen eines PSM oder Strukturen eines
PSM auf Code ab. Die Transformationssregeln sind in einer Transformationsdenition angege-
ben.
Einzelne Transformationsregel bildet Strukturen einer Modellsprache auf Strukturen einer ande-
ren (Modell-)Sprache ab.
dazu sind exakt denierte Modellsprachen notwen
MDA setzt insbesondere auf UML 2.0, es sind aber beliebige exakt denierte Sprachen
denkbar.
Start- und Zielsprache einer Transformation k onnen identisch sein: Ein PIM in UML kann
in ein PSM in UML uberf uhrt werden.
Transformationsdenitionen ben otigen Wissen
uber eine bestimmte Plattform, um plattformunabh angige Strukturen des PIM in platt-
formspezische Strukturen des PSM uberf uhren
uber den Anwendungsbereich, um Strukturen des PIM interpretieren zu k onnen
Aufgrund der vielf altigen Anwendungsbereiche kann es keine allumfassenden Transformations-
denitionen geben.
Benutzer (zB. Firma) muss in der Regel seine eigenen Transformationsdenitionen erstellen
Entwickler implementieren nicht mehr Code, sondern Transformationsdenitionen
Es wird zwischen generischen und speziellen Transformationsregeln unterschieden.
generisch: f ur Architekturen und Patterns, Anbindungen an spezielle Plattformen, Optimierun-
gen
Diese Transformationsregeln sind idealerweise schon vorhanden und k onnen wiederver-
wendet werden.
speziell: Wissen uber den Anwendungsbereich vom Benutzer zu erstellen
291
14.3 Standards und Metamodelle
Um Transformationen automatisch durchf uhren zu lassen, werden Transformationswerkzeuge
ben otigt. Zur Bearbeitung eines PIM wird eine passende Transformationsdenition eingegeben.
F ur verschiedene Aspekte eines Systems werden h aug verschiedene Modellierungssprachen
verwendet: GUI-Builder f ur GUI, ER-Diagramme f ur Datenbanken, UML f ur Anwendungslogik
PIM und PSM sind Konglomerate aus verschiedenen Teilmodellen.
Transformationsdenitionen m ussen h aug Informationen aus verschiedenen Teilmodellen kom-
binieren. Damit Transformationssprachen verschiedene Kombinationen von Modellierungsspra-
chen behandeln k onnen, ben otigen sie einen Standard f ur Modellierungssprachen.
Transformationswerkzeuge sollen mit verschiedenen Sprachen f ur Transformationsdenitionen
und mit verschiedenen Modellierungssprachen arbeiten k onnen
daher ist auch ein Standard f ur Transformationssprachen n otig
MDA verwendet folgendes Schema f ur Standardisierung von Modellen:
MOF Metamodell
UML Metamodell
UML Modell
Objekt
M0
M1
M2
M3 Meta-Metamodell
Metamodell
Modell
Instanz
292
Ebene M0 enth alt die tats achlichen Daten.
Die Modelle f ur die Daten sind in Ebene M1 angesiedelt. Bsp: UML
Ebene M2: Alle Modelle sind Instanzen eines Metamodells. Das Metamodell deniert die
Modellierungssprache. Bsp: UML-Metamodell
Ebene M3: Damit Transformationen mit Modellen verschiedener Metamodelle arbeiten
k onnen, gibt es ein Meta-Metamodell (MOF, Meta Object Facility), das die Metamodelle
deniert.
Das Meta-Metamodell ist durch sich selbst deniert, es gibt also kein Meta-Meta-Metamodell
F ur Transformationsdenitionen existiert zur Zeit noch kein Standard. OMG entwickelt den
Standard QVT (Query, View, Transformation).
Mithilfe des Meta-Metamodells und eines Standards f ur Transformationssprachen k onnen Trans-
formationswerkzeuge konstruiert werden, die unabh angig von der verwendeten Modellierungs-
sprache arbeiten k onnen.
Information zum Umgang mit konkreter Modellierungssprache ist in Transformationsdeni-
tion gekapselt.
erm oglicht Verwendung Anwendungsbereich-spezischer Modellierungssprachen (Domain
Specic Languages, DSL), die dem Meta-Metamodell gen ugen
Domain Specic Languages sind auf einen bestimmten Aufgabenbereich zugeschneiderte
Modellierungssprachen.
h aug Erweiterungen von UML, die nicht das UML-Metamodell erf ullen, aber das Meta-
Metamodell.
293
14.4 Ans atze zur Modelltransformation
Es gibt verschiedene Schemata, wie Transformationen durchgef uhrt werden.
Transformation uber Metamodelle
Eine Transformationsdenition kann Konzepte des PIM-Metamodells direkt auf Konzepte des
PSM-Metamodells abbilden. Dies ist das von MDA angestrebte Verfahren.
PIM
PSM
Transformations-
definition
Transformation
Plattformunabh.
Metamodell
Plattformabh.
Metamodell
Quellsprache
Zielsprache
verwendete
Sprache
verwendete
Sprache
Problem: Die Modellsprache f ur das PIM muss ausreichend detailliert sein. Transformationde-
nitionen k onnen entsprechend aufwendig werden.
294
Transformation uber Annotierungen
Zur Transformation von Strukturen im PIM zu Strukturen im PSM wird das PIM annotiert.
Annotierungen werden von der Transformation als zus atzliche Information verwendet, um Struk-
turen des PSM in Strukturen des PIM zu uberf uhren.
Typisches Szenario: Zu gew ahlter Plattform existiert Transformationsdenition, die eine Menge
von m oglichen Markierungen vorgibt. Entwickler muss PIM in Zwischenschritt annotieren.
PIM
markiertes
PIM
PSM
Plattform
Transformations-
definition
Markierungen
Transformation
Beispiel: UML Stereotypes
Die Objekte einer Klasse Kunde im PIM sollen im implementierten System in einer Da-
tenbank gehalten werden. Die Transformationsdenition sieht vor, derartige Klassen mit
dem Stereotyp <<persistent>> zu markieren.
Kunde
-vorname: String
-nachname: String
-gebDatum: Date
<<<<persistent>>>>
Kunde
-vorname: String
-nachname: String
-gebDatum: Date
Markieren
Vorteil: Einfache oder allgemeine Modellierungssprache f ur PIM verwendbar (zB. UML mit
Stereotypes)
Nachteil: Manueller Zwischenschritt erforderlich
295
Transformation uber Modelle
Eine Transformationsdenition bildet die Typen der Modellsprache des PIM auf Typen der Mo-
dellsprache PSM ab.
Unterschied zu vorherigen Ans atzen: Transformation bildet Typen auf Typen ab, nicht Sprach-
konzepte auf Sprachkonzepte.
PIM
PSM
Transformations-
definition
Transformation
Plattformunabh.
Typen
Plattformabh.
Typen
Quell-Typen
Ziel-Typen
Teilmenge
Teilmenge
296
14.5 Beispiel: Rosas Breakfast Service
1
Rosas Breakfast Service ist ein Betrieb, bei denen Kunden bestimmte Sorten von Fr uhst ucks-
Buffets bestellen k onnen, die dann zum Kunden ins Haus geliefert werden. Der Betrieb m ochte
neben telefonischen Bestellungen auch einen Internet-Auftritt anbieten.
Angebot: verschiedene Standard-Fr uhst ucke, aus bestimmten Zusammensetzungen verschiede-
ner Lebensmittel (comestible). Kunde hat die M oglichkeit, die Zusammensetzung zu modi-
zieren. Kunde kann mehrere Bestellungen aufgeben, eine Bestellung kann mehrere Fr uhst ucke
umfassen.
Daraus l asst sich folgendes PIM konstruieren:
BreakfastOrder
deliveryAddress: Address
deliveryDate: Date
deliveryTime: Date
discount: Real
orderDate: Date
calculatePrice()
Customer
accountNumber: Integer
address: Address
createOrder()
Breakfast
number: Integer
StandardBreakfast
name: String
price: Real
style: String
Change
quantity: Integer
Comestible
name: Strig
minimalQuantity: Integer
price: Real
transportForm: String
Part
quantity: Integer
orders
1..*
customers
1
breakfast
1..*
order
1
* standard
1
*
comestible
*
*
comestible
1..*
1
Jos Warmer und Anneke Kleppe, MDA explained, Addison-Wesley, 2005, Kap.4-6
297
Der Internet-Auftritt soll mit Hilfe einer three-tier-Architektur realisiert werden: einer relatio-
nalen Datenbank, der Anwendungslogik und einem Web-Interface. Das PSM besteht damit aus
drei Teilmodellen, je eines f ur die drei Komponenten.
Plattformen: F ur die Datenbank soll eine SQL-Datenbank verwendet werden, f ur die Anwen-
dungslogik Enterprise Java Beans und f ur das Web-Interface Java Server Pages. Da hier keine
Einf uhrung zu Enterprise Java Beans oder Java Server Pages gegeben werden kann, werden nur
die Transfomationen PIMDatenbank-PSMCode pr asentiert.
298
14.5.1 Transformation PIMDatenbank-PSM
Die Transformationsdenition enth alt folgende Regeln:
1. UML Klassen werden auf Tabellen abgebildet, wobei die Attribute auf Tabellenspalten ab-
gebildet werden. Es wird ein k unstlicher Schl ussel vom Typ INTEGER erzeugt. Attribute,
die selber Klassen sind, werden durch Fremdschl ussel auf deren Tabellen referenziert.
2. Abbildung von UML Strings auf SQL VARCHAR(40), von UML Integer auf SQL INTE-
GER, von UML Date auf SQL DATE und von UML Real auf SQL REAL
3. UML Datentypen ohne Operationen (wie Address) werden auf eine Menge von Tabellen-
spalten abgebildet, wobei jede Spalte ein Feld des Datentyps darstellt.
4. Regel zur Multiplizit at von Assoziationen:
if (Assoziation A nach B ist mit
einer Assoziationsklasse versehen ||
Assoziation A nach B hat
an beiden Enden Multiplizitat > 1)
erzeuge eine eigene Tabelle fur Assoziationsklasse
erzeuge in dieser Tabelle Fremdschlussel auf A und B
else
if (Multiplizitat ist an einem Ende > 1)
in der Tabelle fur die Klasse an diesem Ende:
erzeuge einen Fremdschlussel auf andere Tabelle
else // 1 zu 1 -Beziehung
erzeuge in einer der beiden Tabelle einen
Fremschlussel auf die andere
299
Diese Regeln erzeugen dann folgendes PSM f ur die Datenbank-Komponente:
Customer
customerID: INTEGER (PK)
accountNumber: INTEGER
addressPostalCode: VARCHAR(40)
adressCity: VARCHAR(40)
addressStreet: VARCHAR(40)
addressStreetNumber: VARCHAR(40)
addressTelephoneNumber: VARCHAR(40)
BreakfastOrder
breakfastOrderID: INTEGER (PK)
customerID: INTEGER (FK)
addressPostalCode: VARCHAR(40)
adressCity: VARCHAR(40)
addressStreet: VARCHAR(40)
addressStreetNumber: VARCHAR(40)
addressTelephoneNumber: VARCHAR(40)
deliveryDate: DATE
deliveryTime: DATE
discount: REAL
orderDate: DATE
Breakfast
breakfastID: INTEGER (PK)
standardBreakfastID: INTEGER (FK)
breakfastOrderID: INTEGER (FK)
number: INTEGER
StandardBreakfast
standardBreakfastID: INTEGER (PK)
name: VARCHAR(40)
price: REAL
style: VARCHAR(40)
Comestible
comestibleID: INTEGER (PK)
name: VARCHAR(40)
minimalQuantity: INTEGER
price: REAL
transportForm: VARCHAR(40)
Change
breakfastID: INTEGER (FK)
comestibleID: INTEGER (FK)
quantity: INTEGER
Part
standardBreakfast: INTEGER (FK)
comestibleID: INTEGER (FK)
quantity: INTEGER
*
1
1..n
300
Regel 1
F ur Klassen BreakfastOrder, Customer, Breakfast, StandardBreakfast und
Comestible wird je eine Tabelle angelegt. Sie erh alt je einen k unstlichen Schl ussel
(im Diagramm mit PK markiert).
Regel 2 erzeugt entsprechende Spalten in den Tabellen
Nach Regel 3 wird der Datentyp Address durch Spalten in den Tabellen f ur Customer
und BreakfastOrder dargestellt.
Regel 4
Die Assoziationsklassen Change und Part erf ullen die erste Bedingung. F ur sie wird
je eine Tabelle angelegt und mit Fremdschl usseln auf die Tabellen der assoziierten
Klassen versehen.
Nach der zweiten Bedingung erh alt BreakfastOrder einen Fremdschl ussel auf
Customer und Breakfast erh alt einen Fremdschl ussel auf BreakfastOrder.
301
14.5.2 Transformation Datenbank-PSMCode
Folgende Regeln transformieren das PSM in SQL-Anweisungen:
1. F ur alle Tabellen:
erzeuge Text CREATE TABLE, gefolgt vom Namen und (
f uhre Regeln 2 und 3 aus und beende Text mit )
2. F ur alle Spalten der Tabelle:
erzeuge Text f ur Name und Typname
falls Spalte Fremdschl ussel auf Tabelle name ist, erzeuge Text
REFERENCES name
f uge ein Komma ans Ende
3. erzeuge Text PRIMARY KEY (, f uge die Namen der Spalten ein, die den Schl ussel
bilden, und beende Text mit )
Aus dem PSM wird dann der folgende Code erzeugt. Mit diesem Code k onnen dann die Tabellen
in der Datenbank angelegt werden:
CREATE TABLE Customer (
customerID INTEGER,
accountNumber INTEGER,
addressPostalCode VARCHAR(40),
addressCity VARCHAR(40),
addressStreet VARCHAR(40),
addressStreetNumber VARCHAR(40),
addressTelephoneNumber VARCHAR(40),
PRIMARY KEY (customerID)
)
CREATE TABLE BreakfastOrder (
breakfastOrderID INTEGER,
customerID INTEGER REFERENCES Customer,
addressPostalCode VARCHAR(40),
addressCity VARCHAR(40),
addressStreet VARCHAR(40),
addressStreetNumber VARCHAR(40),
addressTelephoneNumber VARCHAR(40),
deliveryDate DATE,
deliveryTime DATE,
discount REAL,
302
orderDate DATE,
PRIMARY KEY (breakfastOrderID)
)
CREATE TABLE Breakfast (
breakfastID INTEGER,
standardBreakfastID INTEGER REFERENCES StandardBreakfast,
breakfastOrderID INTEGER REFERENCES BeakfastOrder,
number INTEGER,
PRIMARY KEY (breakfastID)
)
CREATE TABLE StandardBreakfast (
standardBreakfastID INTEGER,
name VARCHAR(40),
price REAL,
style VARCHAR(40),
PRIMARY KEY (standardBreakfastID)
)
CREATE TABLE Comestible (
comestibleID INTEGER,
name VARCHAR(40),
minimalQuantity Integer,
transportForm VARCHAR(40),
PRIMARY KEY (comestibleID)
)
CREATE TABLE Change (
breakfastID INTEGER REFERENCES Breakfast,
comestibleID INTEGER REFERENCES Comestible,
name VARCHAR(40),
quantity Integer,
PRIMARY KEY (breakfastID, comestibleID)
)
CREATE TABLE Part (
standardBreakfastID INTEGER REFERENCES StandardBreakfast,
comestibleID INTEGER REFERENCES Comestible,
name VARCHAR(40),
quantity Integer,
PRIMARY KEY (standardBreakfastID, comestibleID)
)
303
14.6 MDA: Vorteile und Nachteile
Vorteile:
Standard-Aufgaben lassen sich automatisieren
Zeitersparnis und gleichbleibende Code-Qualit at
Einfacherer Wechsel der Plattform oder der Sprache
Deutliche Abstraktion des Systems von der verwendeten Plattform
Fokus liegt auf Anwendungslogik
Durch Fokussierung auf das Modell mehr Gewicht auf den Entwurf
Nachteile:
Algorithmen lassen sich nicht aus Modellen generieren, sondern m ussen von Hand imple-
mentiert werden
Durch manuelle
Anderungen am generierten Code besteht Gefahr, dass Modell und Imple-
mentierung divergieren zus atzliche Arbeit, Code und Modell konsistent zu halten
Semantik l asst sich schwer in Modellen ausdr ucken
komplexe Transformationen schwierig zu entwickeln
Es existiert zur Zeit kein Standard f ur Transformationssprachen.
304
Kapitel 15
Refactoring
In diesem Kapitel werden wir untersuchen, wie die Struktur eines objektorientierten Entwurfs
verbessert werden kann.
Hiermit kann man nicht nur Entw urfe, sondern auch bereits codierte Systeme uberarbeiten.
15.1 Refactoring im
Uberblick
Refactoring (w ortl.
Wort-f ur-Wort-
Anderung der Preisberechnung: was passiert, wenn neue Regeln eingef uhrt werden?
An wieviel Stellen mu das Programm ge andert werden?
Ziel: Die einzelnen Faktoren (Preisberechnung, Bonuspunkte) voneinander trennen!
308
15.4 Methoden aufspalten (
Extract Method)
Als ersten Schritt m ussen wir die viel zu lange statement()-Methode aufspalten. Hierzu
f uhren wir das Refactoring-Verfahren
Extract Method ist eine der verbreitetsten Refactoring-Methoden. Sie hat die allgemeine Form:
Es gibt ein Codest uck, das zusammengefat werden kann.
Wandle das Codest uck in eine Methode, deren Name den Zweck der Metho-
de erkl art:
void printOwing(double amount)
printBanner();
// print details
System.out.println("name: " + _name);
System.out.println("amount: " + amount);
wird zu
void printOwing(double amount)
printBanner();
printDetails(amount);
Spezisches Problem: Umgang mit lokalen Variablen, deren Werte explizit in die neue Methode
ubertragen werden m ussen (und ggf. wieder zur uck).
Anwendung auf n achster Seite; zus atzlich Umbenennung von each in aRental.
309
1 public String statement() {
2 double totalAmount = 0.00;
3 int frequentRenterPoints = 0;
4 Enumeration rentals = _rentals.elements();
5 String result = "Rental Record for " + getName() + "\n";
6
7 while (rentals.hasMoreElements()) {
8 Rental each = (Rental) rentals.nextElement();
9 double thisAmount = amountFor(each); // NEU
10
11 // Bonuspunkte berechnen
12 frequentRenterPoints++;
13
14 if ((each.getMovie().getPriceCode() == Movie.NEW_RELEASE) &&
15 each.getDaysRented() > 1)
16 frequentRenterPoints++;
17
18 // Zeile berechnen
19 result += "\t" + each.getMovie().getTitle() + "\t" +
20 String.valueOf(thisAmount) + "\n";
21 totalAmount += thisAmount;
22 }
23
24 // Summe
25 result += "Amount owed is " + String.valueOf(totalAmount) + "\n";
26 result += "You earned " + String.valueOf(frequentRenterPoints) +
27 " frequent renter points";
28 return result;
29 }
30
31 public double amountFor(Rental aRental) { // NEU
32 double thisAmount = 0.00;
33
34 switch (aRental.getMovie().getPriceCode()) {
35 case Movie.REGULAR:
36 thisAmount += 2.00;
37 if (aRental.getDaysRented() > 2)
38 thisAmount += (aRental.getDaysRented() - 2)
*
1.50;
39 break;
40
41 case Movie.NEW_RELEASE:
42 thisAmount += aRental.getDaysRented()
*
3.00;
43 break;
44
45 case Movie.CHILDRENS:
46 thisAmount += 1.50;
47 if (aRental.getDaysRented() > 3)
48 thisAmount += (aRental.getDaysRented() - 3)
*
1.50;
49 break;
50 }
51
52 return thisAmount;
53 }
310
15.5 Bewegen von Methoden (
Move Method)
Die Methode amountFor hat eigentlich nichts beim Kunden zu suchen; vielmehr geh ort sie zum
Ausleihvorgang selbst. Hierf ur setzen wir das Refactoring-Verfahren
wird zu
if (basePrice() > 1000.00)
return basePrice()
*
0.95;
else
return basePrice()
*
0.98;
double basePrice()
return quantity
*
itemPrice;
(Zum Einwand
Schnittstel-
len und Efzienz).
314
15.6.2 Anwendung
Wir f uhren in der Customer-Klasse zwei private neue Methoden ein:
getTotalCharge() summiert die Kosten
getTotalFrequentRenterPoints() summiert die Bonuspunkte
1 public String statement() {
2 Enumeration rentals = _rentals.elements();
3 String result = "Rental Record for " + getName() + "\n";
4
5 while (rentals.hasMoreElements()) {
6 Rental each = (Rental) rentals.nextElement();
7
8 result += "\t" + each.getMovie().getTitle() + "\t" +
9 String.valueOf(each.getCharge()) + "\n";
10 }
11
12 result += "Amount owed is " + String.valueOf(getTotalCharge()) + "\n";
13 result += "You earned " + String.valueOf(getTotalFrequentRenterPoints()) +
14 " frequent renter points";
15 return result;
16 }
17
18 private double getTotalCharge() { // NEU
19 double charge = 0.00;
20 Enumeration rentals = _rentals.getElements();
21 while (rentals.hasMoreElements()) {
22 Rental each = (Rental) rentals.nextElement();
23 charge += each.getCharge();
24 }
25 return charge;
26 }
27
28 private int getTotalFrequentRenterPoints() { // NEU
29 int points = 0;
30 Enumeration rentals = _rentals.getElements();
31 while (rentals.hasMoreElements()) {
32 Rental each = (Rental) rentals.nextElement();
33 points += each.getFrequentRenterPoints();
34 }
35 return points;
36 }
Die statement()-Methode ist schon deutlich k urzer geworden!
315
15.6.3 Klassen nach dem Einf uhren von Queries
Neue private Methoden getTotalCharge und getTotalFrequentRenterPoints:
Movie
+REGULAR: int = 0
+NEW_RELEASE: int = 1
+CHILDRENS: int = 2
-priceCode: int
-title: String
+getPriceCode(): int
+setPriceCode(code:int)
+getTitle(): String
Rental
-daysRented: int
+getDaysRented(): int
+getMovie(): Movie
+getCharge(): double
+getFrequentRenterPoints(): int
movie 0..*
1
rentals
1
0..*
Customer
-name: String
+addRental(rental:Rental)
+getName(): String
+statement(): String
-getTotalCharge(): double
-getTotalFrequentRenterPoints(): int
15.6.4 Sequenzdiagramm nach dem Einf uhren von Queries
statement()
getTotalCharge()
getCharge()
getFrequentRenterPoints()
: Rental
: Movie
: Customer
getPriceCode()
getPriceCode()
getTotalFrequentRenterPoints()
316
15.6.5 Einf uhren einer HTML-Variante
Da die Berechnungen von Kosten und Bonuspunkten nun komplett herausfaktorisiert sind, kon-
zentriert sich statement() ausschlielich auf die korrekte Formatierung.
Nun ist es kein Problemmehr, alternative Rechnungs-Formate auszugeben. Die Methode htmlStatement()
etwa k onnte die Rechnung in HTML-Format drucken:
1 public String htmlStatement() {
2 Enumeration rentals = _rentals.elements();
3 String result = "<H1>Rental Record for <EM>" + getName() + "</EM></H1>\n";
4
5 result += "<UL>";
6 while (rentals.hasMoreElements()) {
7 Rental each = (Rental) rentals.nextElement();
8
9 result += "<LI> " + each.getMovie().getTitle() + ": " +
10 String.valueOf(each.getCharge()) + "\n";
11 }
12 result += "</UL>";
13
14 result += "Amount owed is <EM>" + String.valueOf(getTotalCharge()) +
15 "</EM><P>\n";
16 result += "You earned <EM>" +
17 String.valueOf(getTotalFrequentRenterPoints()) +
18 "</EM> frequent renter points<P>";
19 return result;
20 }
317
15.7 Weiteres Verschieben von Methoden
Wir betrachten noch einmal die Methode getCharge() aus der Klasse Rental.
1 class Rental {
2 // ...
3 public double getCharge() { // NEU
4 double charge = 0.00;
5
6 switch (getMovie().getPriceCode()) {
7 case Movie.REGULAR:
8 charge += 2.00;
9 if (getDaysRented() > 2)
10 charge += (getDaysRented() - 2)
*
1.50;
11 break;
12
13 case Movie.NEW_RELEASE:
14 charge += getDaysRented()
*
3.00;
15 break;
16
17 case Movie.CHILDRENS:
18 charge += 1.50;
19 if (getDaysRented() > 3)
20 charge += (getDaysRented() - 3)
*
1.50;
21 break;
22 }
23
24 return charge;
25 }
26 }
Grunds atzlich ist es eine schlechte Idee, Fallunterscheidungen aufgrund der Attribute anderer
Objekte vorzunehmen. Wenn schon Fallunterscheidungen, dann auf den eigenen Daten.
Folge getCharge() sollte in die Klasse Movie bewegt werden, und wenn wir schon dabei
sind, auch getFrequentRenterPoints():
Rental
-daysRented: int
+getDaysRented(): int
+getMovie(): Movie
+getCharge(): double
+getFrequentRenterPoints(): int
movie 0..*
1
rentals
1
0..*
Customer
-name: String
+addRental(rental:Rental)
+getName(): String
+statement(): String
+htmlStatement(): String
-getTotalCharge(): double
-getTotalFrequentRenterPoints(): int
Movie
+REGULAR: int = 0
+NEW_RELEASE: int = 1
+CHILDRENS: int = 2
-priceCode: int
-title: String
+getPriceCode(): int
+setPriceCode(code:int)
+getTitle(): String
+getCharge(daysRented:int): double
+getFrequentRenterPoints(daysRented:int): int
318
Klasse Movie mit eigenen Methoden zur Berechnung der Kosten und Bonuspunkte:
1 class Movie {
2 // ...
3 public double getCharge(int daysRented) { // NEU
4 double charge = 0.00;
5
6 switch (getPriceCode()) {
7 case Movie.REGULAR:
8 charge += 2.00;
9 if (daysRented > 2)
10 charge += (daysRented - 2)
*
1.50;
11 break;
12
13 case Movie.NEW_RELEASE:
14 charge += daysRented
*
3.00;
15 break;
16
17 case Movie.CHILDRENS:
18 charge += 1.50;
19 if (daysRented > 3)
20 charge += (daysRented - 3)
*
1.50;
21 break;
22 }
23
24 return charge;
25 }
26
27 public int getFrequentRenterPoints(int daysRented) { // NEU
28 if ((getPriceCode() == Movie.NEW_RELEASE) && daysRented > 1)
29 return 2;
30 else
31 return 1;
32 }
33 }
In der Rental-Klasse delegieren wir die Berechnung an das jeweilige Movie-Element:
1 class Rental {
2 // ...
3 public double getCharge() { // NEU
4 return getMovie().getCharge(_daysRented);
5 }
6
7 public int getFrequentRenterPoints() { // NEU
8 return getMovie().getFrequentRenterPoints(_daysRented);
9 }
10 }
319
15.8 Fallunterscheidungen durch Polymorphie ersetzen
(
wird zu
Bird
+getSpeed()
European
+getSpeed()
African
+getSpeed()
Norwegian Blue
+getSpeed()
2
http://www.pythonet.org/pet-shop.html
320
15.8.2 Neue Klassenhierarchie Erster Versuch
Movie
-title: String
+getTitle(): String
+getCharge(daysRented:int): double
+getFrequentRenterPoints(daysRented:int): int
Regular Movie
+getCharge(daysRented:int): double
New Release Movie
+getCharge(daysRented:int): double
+getFrequentRenterPoints(daysRented:int): int
Childrens Movie
+getCharge(daysRented:int): double
Neue Eigenschaften:
Die Berechnung der Kosten wird an die Unterklassen abgegeben (abstrakte Methode getCharge)
Die Berechnung der Bonuspunkte steckt in der Oberklasse, kann aber von Unterklassen
uberladen werden (Methode getFrequentRenterPoints())
Problem dieser Hierarchie: Beim Erzeugen eines Movie-Objekts mu die Klasse bekannt sein;
w ahrend ihrer Lebensdauer k onnen Objekte nicht mehr einer anderen Klasse zugeordnet werden.
Im Videoverleih kommt dies aber durchaus vor (z.B.
Ubergang von
Neuerscheinung zu
nor-
malem Video oder
Kindervideo zu
Anderungen w ahrend der Programmierung sind jedoch gef ahrlich, da bestehende Funktionalit at
gef ahrdet sein k onnte (
Anderung).
Beispiel: Automatisches Testen mit JUnit
JUnit von Kent Beck und Erich Gamma ist ein Testrahmen f ur Regressionstests von Java-Komponenten.
2
Ziel von JUnit ist, die Produktion hochwertigen Codes zu beschleunigen.
Analog: CPPUnit f ur C++-Programme
Testf alle
JUnit stellt Testf alle (Testcase) bereit, organisiert nach demCommand-Pattern (Abschnitt 12.7).
Ein Testfall besteht aus einer Menge von Testmethoden, die jeweils einen bestimmten Test reali-
sieren. Zur Kennzeichnung als Testmethode wird eine Methode mit einer Annotation
@org.junit.Test versehen.
@org.junit.Test
public void foo() ...
In der Methode kann die assertTrue()-Methode der Klasse org.junit.Assert aufgerufen
werden, um erwartete Eigenschaften zu uberpr ufen.
Zum Initialisieren einer Testumgebung wird eine entsprechende Methode erstellt und mit der An-
notation @org.junit.Before versehen. Sollen nach einemTest Ressourcen der Testumgebung
freigegeben werden, wird eine entsprechende Methode implementiert und mit @org.junit.After
annotiert. Diese Methoden werden vor bzw. nach jeder Testmethode ausgef uhrt.
2
http://www.junit.org/
332
Testsuiten
Die Tests eines Testfalls werden in einer Testsuite zusammengefat, die von einer statischen
Methode suite() zur uckgegeben werden. Testsuiten k onnen ebenfalls Testsuiten enthalten
(Composite-Pattern, Abschnitt 12.4).
public static junit.framework.Test suite()
return new JUnit4TestAdapter(Tests.class);
333
Beispiel: Testen eines Warenkorbs
3
Die Klasse ShoppingCart (Warenkorb; hier nicht angegeben) enth alt Methoden zum Hin-
zuf ugen und L oschen von Produkten sowie zum Abfragen der Produktanzahl und des Gesamt-
preises.
Wir implementieren einen Testfall als Klasse ShoppingCartTest, der die Funktionalit at der
Klasse testet.
Teil 1: Initialisierung
enth alt das Erzeugen und Zerst oren der Testumgebung
import org.junit.Assert;
import junit.framework.JUnit4TestAdapter;
public class ShoppingCartTest
private ShoppingCart bookCart;
// Testumgebung erzeugen
// Wird vor jeder Testmethode aufgerufen
@org.junit.Before
public void runBeforeEachTest
bookCart = new ShoppingCart();
Product book =
new Product("Extreme Programming", 23.95);
bookCart.addItem(book);
3
Aus: Mike Clark, JUnit Primer, http://www.clarkware.com/articles/JUnitPrimer.html
334
Teil 2: Tests
Jeder Test wird als eigene Methode realisiert.
Ein Test f uhrt einige Methoden aus und pr uft dann, ob der Zustand den Erwartungen entspricht.
Wenn nicht, gibt es einen Fehler.
Beispiel: Test auf leeren Warenkorb. Erst wird der Warenkorb geleert, dann wird gepr uft, ob er
auch tats achlich leer ist.
// Test auf leeren Warenkorb
@org.junit.Test
public void emptyCart()
bookCart.empty();
Assert.assertTrue( bookCart.isEmpty());
Hierbei benutzen wir die statischen Hilfsmethoden der importierten Klasse Assert:
fail(msg) meldet einen Fehler namens msg
assertTrue(msg, b) meldet einen Fehler, wenn Bedingung b unwahr ist
assertEquals(msg, v
1
, v
2
) meldet einen Fehler, wenn v
1
,= v
2
assertEquals(msg, v
1
, v
2
, ) meldet einen Fehler, wenn [ v
1
- v
2
[>
assertNull(msg, object) meldet einen Fehler, wenn object nicht null ist
assertNonNull(msg, object) meldet einen Fehler, wenn object null ist
335
Weitere Tests: Funktioniert das Hinzuf ugen von Objekten?
// Test auf Hinzufugen
@org.junit.Test
public void addProduct()
Product book = new Product("Refactoring", 53.95);
bookCart.addItem(book);
double expectedBalance = 23.95 + book.getPrice();
double currentBalance = bookCart.getBalance();
double tolerance = 0.0;
Assert.assertEquals(expectedBalance, currentBalance,
tolerance);
int expectedItemCount = 2;
int currentItemCount = bookCart.getItemCount();
Assert.assertEquals(expectedItemCount,
currentItemCount);
336
Gibt es eine Ausnahme, wenn ich ein unbekanntes Produkt l oschen m ochte?
Zum Testen von Exceptions erweitert man die Annotation um eine Angabe der erwarteten Ex-
ception. Wird diese nicht erzeut, schl agt der Test fehl.
// Test auf Entfernen eines unbekannten Produkts
@org.junit.Test (expected=ProductNotFoundException.class)
public void productNotFound()
Product book =
new Product("Enders Game", 4.95);
// hier sollte stets eine
// ProductNotFoundException entstehen
bookCart.removeItem(book);
337
Teil 3: Testsuite
Die Klasse wird mit einer Methode suite() abgeschlossen, die die einzelnen Testf alle zu einer
Testsuite zusammenfat. Alle annotierten Methoden werden Teil der Testsuite.
// Testsuite erstellen
public static junit.framework.Test suite()
return new JUnit4TestAdapter(ShoppingCartTest.class);
Teil 4: Starten
Die Hauptmethode main() ruft ein GUI f ur genau diesen Testfall auf. Das hier beschriebene JU-
nit 4 besitzt (noch) keine graphische Anzeige. Allerdings kann das GUI der JUnit 3.x- Versionen
verwendet werden:
// Hauptmethode: Ruft GUI auf
public static void main(String args[])
String[] testCaseName =
ShoppingCartTest.class.getName() ;
// Klasse aus alterer JUnit-Version
junit.swingui.TestRunner.main(testCaseName);
Klassisches Spezikationsverfahren
Vorbedingungen beschreiben die Voraussetzungen zur Ausf uhrung einer Funktion. Hierzu geh oren:
Aussagen uber die Eingabeparameter
Aussagen uber den Programmzustand (sichtbar und unsichtbar)
Nachbedingungen beschreiben den Effekt, den die Ausf uhrung einer Funktion bewirkt. Hierzu
geh oren:
Aussagen uber die Ausgabeparameter
Aussagen uber den Programmzustand
jeweils in Abh angigkeit vom Vorzustand und den Eingabeparametern
340
16.3.1 Beispiel: Sortieren eines Feldes
Aufgabe: Ein Feld zahlen[0..n 1] von n Integers soll sortiert werden.
Vorbedingung (trivial):
n 0
Nachbedingung:
is-sorted(zahlen, n) is-permutation-of (zahlen,
zahlen, n)
mit
is-sorted(a, n) = i 1, . . . , n 1 : a[i 1] a[i]
und
is-permutation-of (a, a
, n) =
i 0, . . . , n 1 : occ(a, a[i]) = occ(a
, a[i])
occ(a, x) =
k [ a[k] = x
Hierbei steht
zahlen f ur den
alten Wert von zahlen vor der Ausf uhrung der Funktion.
Die Nachbedingung gibt nur an, was passiert, nicht jedoch, wie dies passiert!
Eine m ogliche Realisierung (in Java):
public static void shell sort(int zahlen[], int n)
int h = 1;
do
h = h
*
3 + 1;
while (h <= n);
do
h /= 3;
for (int i = h; i < size; i++)
int v = zahlen[i];
for (int j = i; j >= h && zahlen[j - h] > v;
j -= h)
zahlen[j] = zahlen[j - h];
if (i != j)
zahlen[j] = v;
while (h != 1);
341
16.3.2 Beispiel: Maximal m oglicher Spekulationsgewinn
4
Der Kurs einer Aktie an n aufeinanderfolgenden Tagen ist als Feld kurs[0..n 1] von Integers
gegeben. Gesucht sind kauftag und verkauftag, so da der Gewinn bestprot (Kursdifferenz zwi-
schen Kauf- und Verkauftag) maximal wird.
Vorbedingung:
n > 0 i 0, . . . , n 1 : kurs[i] > 0
Nachbedingung:
bestprot = kurs[verkauftag] kurs[kauftag]
= max
_
kurs[i] kurs[j] [ i, j 0, . . . , n 1 j < i
_
Realisierung (in Java):
public static int kauftag;
public static int verkauftag;
public static int best profit(int kurs[], int n)
return profit;
4
aus Vordiplomsklausur
// Nachbedingung
assert(profit == kurs[verkauftag] - kurs[kauftag]);
return profit;
5
Bestandteil von Java 1.4
343
16.4 Spezikation von Klassen und Objekten
Wichtigste Mittel zur Spezikation von Klassen und Objekten:
Vor- und Nachbedingungen
Klassen- und Typinvarianten
16.4.1 Vor- und Nachbedingungen
Methoden von Klassen und Objekten k onnen mittels Vor- und Nachbedingungen speziziert
werden.
Bei Methoden von Objekten muss auf Vererbung geachtet werden: werden public- oder protected-
Methoden uberschrieben, sind die Vor- und Nachbedingungen der uberschriebenen Methode zu
ber ucksichtigen.
H auges Ziel bei Vererbung: Objekte einer Unterklasse U verhalten sich bez uglich der Methoden
wie Objekte der Oberklasse O
Objekte von U k onnen als Objekte der Oberklasse O verwendet werden
Dies wird als Verhaltenskonformanz bezeichnet.
Dazu muss folgendes f ur s amtliche uberschriebene Methoden m von O gelten:
Wenn die Vorbedingung von m erf ullt ist, muss auch die Vorbedingung der uberschreiben-
den Methode m erf ullt sein.
Wenn die Nachbedingung der uberschreibenden Methode m erf ullt ist, muss auch die
Nachbedingung von m gelten.
Ist dies nicht erf ullt, nennt man U eine Spezialisierung von O.
344
Beispiel
Eine Klasse Bank erlaubt das Geld-Abheben von einem Konto mittels einer Methode abheben.
Sie bietet einen Dispo-Kredit an, der als negativer Wert dargestellt wird - der Betrag, um den das
Konto uberzogen werden darf.
class Bank
int konto;
int dispo;
public Bank(int k, int d)
konto = k;
dispo = d;
= konto - betrag)
345
Eine Subklasse von Bank ist WeihnachtBank, die im Dezember den Dispokredit um 1000 Euro
erh oht. Die Vorbedingung ist hier
Pre(WeihnachtBank k.abheben(int betrag, Date datum))
(datum.month() == Dezember)
(konto - betrag (dispo - 1000) dispo 0)
(datum.month() ! = Dezember)
(konto - betrag dispo dispo 0),
die Nachbedingung ist
Post(WeihnachtBank k.abheben(int betrag, Date datum))
(konto
= konto - betrag)
Der Code der Klasse ist wie folgt:
class WeihnachtBank extends Bank
public WeihnachtBank(int k, int d)
konto = k;
dispo = d;
= konto - betrag)
Folgender Code beschreibt die Klasse:
class KeinDispoBank extends Bank
public KeinDispoBank(int k)
konto = k;
dispo = 0;
void main()
Bank b = new Bank(100, 1000);
Bank w = new WeihnachtBank(100, 1000);
Bank k = new KeinDispoBank(100);
// Diese beiden Aufrufe werden
// problemlos bearbeitet.
abheben(b, 1000, 24.12.06); // konto = -1000
abheben(w, 1000, 24.12.06); // konto = -1000
// Nach diesem Aufruf hat der Benutzer
// sein Konto uberzogen!
abheben(k, 1000, 24.12.06) // konto = -1000
elementData[elementCount++] = obj;
Falls die Klasseninvariante vor Ausf uhrung der Methode gilt, gilt sie auch danach.
Die Methode k onnte aber auch so aussehen:
public synchronized void addElement(E obj)
elementCount++;
if (elementData.length < elementCount)
elementData = makeBiggerArrayAndCopyAllInto();
elementData[elementCount] = obj;
Inkrementierung von elementCount kann die Invariante verletzen, bis das neue Array angelegt
wurde.
erlaubt, da dies innerhalb der Methode geschieht
Angenommen, Methode makeBiggerArrayAndCopyAllInto sei offentliche Methode, dann
kann die Klasseninvariante unmittelbar vor ihrem Aufruf verletzt sein.
erlaubt, da sich das Objekt bereits in einer laufenden Ausf uhrung einer ihrer Methoden ben-
det
7
Dies ist nicht die tats achliche Implementierung der Methode
350
Klasseninvarianten haben deskriptive und normative Funktionen.
normativ
Invariante als Anforderung an die zu implementierende Klasse imSinne einer Spezikation
als Zusicherung f ur Benutzer der Klasse, wenn die Implementierung die Invariante erf ullt
deskriptiv
aus dem Code analysierte Klasseninvarianten
Verwendung: zB. zur Codeoptimierung
Beispiel: Die indexOf-Methode der Vector-Klasse
8
Die indexOf-Methode der Klasse Vector pr uft, ob ein erhaltenes Objekt im Array
elementData enthalten ist und gibt entweder den gefundenen Index oder -1 zur uck.
Eine Implementierung der Methode k onnte so aussehen:
public final synchronized int indexOf(Object elem)
if (elementData != null)
for (int i = 0; i < elementData.length; i++)
if (elem.equals(elementData[i]))
return i;
return -1;
return -1;
8
Das Beispiel zeigt nicht die tats achliche Implementierung der Methode
351
Validierung
Werden Klasseninvarianten zur Spezizikation verwendet, muss bei der Validierung eines Pro-
gramms gepr uft werden, dass der implementierte Code die Invarianten der verwendeten Klassen
auch einh alt.
Hierbei m ussen zwei F alle unterschieden werden:
1. Nachweis der Spezizikation f ur die Implementierung einer Methode
Annahme: Invariante gilt vor der Methode, zu Beweisen: Invariante gilt nach der Methode.
Methoden werden mittels Vor- und Nachbedingungen speziziert. Zum Nachweis, dass
eine Methode foo einer Klasse k die Spezizikation erf ullt: Beweisen, dass, falls ihre
Vorbedingung gilt, nach der Ausf uhrung ihre Nachbedingung erf ullt ist
vor foo nach.
Zur Validierung der Klasseninvarianten I
k
von k muss bei ks offentlichen Methoden bar
zus atzlich I
k
gelten:
I
k
&& vor bar I
k
&& nach
Ausgehend von der Annahme, dass I
k
und vor gelten, muss gezeigt werden, dass nach
Ausf uhrung von bar I
k
und nach gelten.
2. Nachweis, dass vor Aufruf einer offentlichen Methode eines Objekts deren Invariante
gilt
Beweise, dass Invariante vor dem Aufruf gilt. Anschliessend darf angenommen werden,
dass sie auch nach der Ausf uhrung gilt.
Von zentraler Bedeutung bei der Validierung ist die Kapselung der Attribute. Sind die Attribute
gekapselt, kann die Validierung einer Klasseninvarianten auf ihre Klasse beschr ankt werden.
modulare Validierung m oglich (etwa von Bibliotheken)
Ansonsten: programmumfassende Validierung notwendig, da sonst Klassen oder Objekte belie-
big fremde Attribute modizieren k onnen.
352
Vererbung und Typinvarianten
In objektorientierten Sprachen mit Vererbung stellt sich die Frage, ob man statt Klasseninvarian-
ten nicht Typinvarianten verwenden sollte.
Bei Verwendung von Typinvarianten erben Unterklassen die Typinvarianten ihrer Oberklassen.
Wird ein Objekt im Programm als eine Instanz einer Oberklasse verwendet, muss es in diesem
Zusammenhang nur die Typinvariante der Oberklasse erf ullen.
Beispiel
Die Typinvariante der Klasse Person sei Inv(Person) == 0 alter 150.
class Person
String name;
int alter;
...
Student erbt diese Invariante und besitzt zus atzlich eine Bedingung f ur die Matrikelnummern:
Inv(Student) == (0 alter 150) AND (1 MatrNr)
class Student extends Person
int MatrNr;
...
Unterklassen k onnen ererbte Typinvarianten auch versch arfen. Angenommen, Studenten m ussten
vollj ahrig sein, dann w are die Invariante von Student:
Inv(Student) == (0 alter 150) AND (18 alter 150) AND (1 MatrNr),
was sich zu
Inv(Student) == (18 alter 150) AND (1 MatrNr) vereinfachen l asst.
Vor- und Nachteile von Typinvarianten:
Klasseninvarianten sind f ur eine Klasse spezisch und k onnen daher st arker sein
Validierung von Klasseninvarianten ist komplizierter: Disjunktion uber alle m oglichen Ty-
pen bei dynamischer Bindung
Ein Kompromiss:
Bedingungen der Klasseninvarianten als public, private und protected deklarieren. Be-
dingungen, die public oder protected sind, werden wie Typinvarianten verwendet, w ahrend
private Bedingungen spezisch f ur ihre Klasse sind.
wird zB. bei JML (Java Modeling Language) angewandt, einer Spezikationssprache f ur Java
353
16.5 Modellorientierte Spezikation
Modellorientierte Spezikation stellt eine standardisierte Sprache zur Verf ugung, in der Pro-
grammzust ande sowie Vor- und Nachbedingungen auf hohem Abstraktionsniveau ausgedr uckt
werden k onnen.
Auerdem bietet modellorientierte Spezikation eine Methodologie zum Spezizieren und Im-
plementieren korrekter Software.
Eigenschaften der modellorientierten Spezikation:
Volle M achtigkeit der Pr adikatenlogik kann zum Spezizieren verwendet werden
Weitentwickelte Methodologie (VDM, Z)
Gute Lehrb ucher
Gute Werkzeuge
Gute Verwurzelung in modernen programmiersprachlichen Konzepten
Spezikation manchmal ausf uhrbar (rapid prototyping)
automatische Testdatengenerierung; automatisches Orakel
Einsatz von Beweissystemen m oglich, um Eigenschaften der Spezikation automatisch
abzuleiten
Brauchbarkeit in groen Industrieprojekten nachgewiesen
Gewisse Intelligenz des Verwenders erforderlich
354
16.5.1 Aufbau einer VDM-Spezikation
Wir betrachten als Beispiel die Spezikationssprache VDM (Vienna Development Method).
Eine VDM-Spezikation besteht aus
1. Typdenitionen
(aus Basistypen und Typkonstruktoren; u.U. mit Invariante)
2. Denition des globalen Systemzustandes
(Datenobjekt nebst Invariante)
3. Hilfsfunktionen
(Frei von Seiteneffekten; funktionale Sprache inkl. Lambda-Abstraktion, Funktionen h oher-
er Ordnung, Datentypen . . . )
4. Operationen (Seiteneffekt auf Systemzustand); entweder
implizite Spezikation: Vor- / Nachbedingungen
explizite Spezikation: Angabe eines abstrakten funktionalen Ausdruckes (nicht ausf uhr-
bar), eines funktionalen Programms (ausf uhrbar) oder sogar eines prozeduralen Pro-
gramms)
5. Beweisverpichtungen: Nachweis, da explizite Operationen einer Vor- / Nachbedingung
gen ugen; Nachweis, da Operationen die Zustandsinvariante erhalten
6. Verfeinerung (Konkretisierung, Reikation) einer Spezikation:
(a) Angabe einer konkrete(re)n Darstellung f ur Daten (z.B. Liste statt Menge)
(b) Angabe einer Funktion, die einem konkreten Objekt ein abstraktes zuordnet; Nach-
weis der Surjektivit at
(c) Angabe von konkreten
NonEmptyString = char
+
Sequenzen-Literale wie Mengen, aber in [ ]:
kanzler = [ADENAUER, ERHARD, KIESINGER,
BRANDT, SCHMIDT, KOHL, SCHR
ODER]
Aufz ahlungen und Comprehensions wie bei Mengen, z.B.:
[x
3
[ x N 0 x 42]
Operatoren: Erstes Element (hd l), Sequenz ohne erstes Element (tl l), Anzahl Elemente (len l),
Konkatenation (l
1
`
l
2
), Elementmenge (elems l), . . .
hd kanzler = ADENAUER
len tl kanzler = 6
kanzler
`
[STOIBER] = [ADENAUER, . . . , SCHR
ODER, STOIBER]
elems kanzler = ADENAUER, . . . , SCHR
ODER
Vereinfachte Syntax f ur Zeichensequenzen:
"Merkel" = [M, e, r, k, e, l]
358
16.5.5 Records
Typ-Denitionen:
Date :: day : 1, . . . , 31
month : JAN, . . . , DEC
year : Z
Record-Literale uber Typnamen:
ubungstermin = Date(17, DEC, 2001)
Operatoren: Selektion (.) und Modikation (, ):
ubungstermin.year = 2001
( ubungstermin, year 2002) = Date(17, DEC, 2002)
Record-Dekomposition:
let Date(d, m, y) = ubungstermin in d m y
Invarianten uber Datentypen:
.1 inv Date(day, month, year)
.2 month = FEB day 28
.3 month = FEB day = 29 is-leap(year)
.4 month = APR day 30
.5 month = JUN . . .
359
16.5.6 Endliche Abbildungen (Maps)
H augste Struktur in groen Spezikationen!
Typ-Denitionen:
Studname = N
m
String
Map-Literale Aufz ahlungen:
studnamen = 545358 "Fritz Brause",
601962 "Eva Luator"
Leere Abbildung:
Fixpunkt) beschrie-
ben werden
361
16.5.10 Quantoren
All-Quantoren () und Existenz-Quantoren () wie aus der Mathematik bekannt:
n N n 0 = true
n N n
2
= 2 = false
Dar uber hinaus: Existenz genau eines Elements (! ) . . .
! n N n div 2 = 1 = false
! n N n + 2 = 4 = true
. . . und Iota-Ausdr ucke ( , Auswahl des einen Elements):
n N n + 2 = 4 = 2
Im Allgemeinen unentscheidbar!
362
16.5.11 Funktionen
Funktion im mathematischen Sinn ohne Seiteneffekte!
Implizite Funktionsdenition
Beschreibt das Funktionsergebnis implizit durch von ihm erf ullte Bedingungen (post):
1.0 max1 (N : N-set)m : N
.1 pre N ,=
.2 post m N n N m n
Explizite Funktionsdenition
Gibt das Funktionsergebnis explizit an:
2.0 max2 (N : N-set)m : N
.1 m N n N m n
.2 pre N ,=
Rekursiv ausformuliert:
3.0 max3 (N : N-set)m : N
.1 let m N in
.2 if n N m n then m
.3 else max3(N m)
.4 pre N ,=
363
16.5.12 Operationen
Operationen andern Zust ande!
Beispiel: Taschenrechner (implizit)
i in Register laden:
4.0 LOAD(i : N)
.1 ext wr reg : N
.2 post reg = i
Registerinhalt zur uckgeben:
5.0 SHOW () r : N
.1 ext rd reg : N
.2 post r = reg
Register durch d teilen; Rest in Register lassen:
6.0 DIVIDE (d : N) r : N
.1 ext wr reg : N
.2 pre d ,= 0
.3 post d r + reg =
reg reg < d
<-Funktion
372
16.6.3 O/V-Funktionen und Generatoren
Man unterscheidet
werteliefernde Funktionen (V-Funktionen), die als Ergebnis ein Objekt einer bereits be-
kannten Algebra liefern (hier: ==), und
objekterzeugende Funktionen (O-Funktionen), die als Resultat ein Element der neu zu
denierenden Algebra haben (hier: 0, s, +)
Unter den O-Funktionen gibt es eine ausgezeichnete Teilmenge von Generatoren, die bereits
ausreichen, alle Objekte der Algebra zu erzeugen (hier: 0, s)
Unter den Generatoren ist ublicherweise einer, der ein
== deniert ist!
ALGEBRA SetAlg[Elem]
USES BoolAlg
SORTS Set, Elem, Bool
OPERATIONS
emptyset: Set
add: Set, Elem Set
union: Set, Set Set
intersection: Set, Set Set
difference: Set, Set Set
member: Set, Elem Bool
EQUATIONS
member(emptyset, z) = false
member(add(x,y), z) =
IF y == z THEN true ELSE member(x, z)
union(x, emptyset) = x
union(x, add(y, z)) = add(union(x, y), z)
union(x, y) = union(y, x)
intersection(x, emptyset) = emptyset
intersection(x, add(y, z)) =
IF member(x, z) THEN add(intersection(x, y), z)
ELSE intersection(x, y)
intersection(x, y) = intersection(y, x)
difference(emptyset, x) = emptyset
difference(add(x,y), z) =
IF member(z,y) THEN difference(x,z)
ELSE add(difference(x, z), y)
Ubung.
Bags sind Mengen, in denen Elemente mehrfach vorkommen k onnen. Statt
member(x,y) gibt
es eine Funktion
isempty und
isin
Uberschneiden sich zwei Fenster?
Uberdeckt ein Fenster ein anderes?
Verschieben eines Fensters
Vergr oern eines Fensters
L oschen eines Fensters
Nach vorn holen eines Fensters
Ist ein Fensterausschnitt vollst andig sichtbar?
Fensterkoordinaten (X, Y) und -gr oen sollen als nat urliche Zahlen angegeben werden
Der Bildschirm wird als unendlich gro angenommen; Nullpunkt in der linken oberen Ecke
Jedes Fenster hat eine ganzzahlige Z-Koordinate, die die Tiefe und damit die Sichtbarkeit be-
stimmt (2
1
2
-D Graphik)
Fenster werden der Einfachheit halber durch einen eindeutigen Namen identiziert
Der Fensterinhalt wird von uns ignoriert
Ein Bildschirm ist eine Liste von Fenstern, wobei die Position in der Liste die Z-Koordinate
bestimmt (ganz vorne = vollst andig sichtbar)
380
ALGEBRA WindowAlg USES BoolAlg, NatAlg, StringAlg
SORTS Window, Nat, Bool, String
OPERATIONS
create: Nat, Nat, Nat, Nat, String Window
title: Window String
xpos: Window Nat
ypos: Window Nat
width: Window Nat
height: Window Nat
eqWin: Window, Window Bool
inWin: Nat, Nat, Window Bool
contains: Nat, Nat, Nat, Nat, Window Bool
overlap: Window, Window Bool
move: Window, Nat, Nat Window
resize: Window, Nat, Nat Window
EQUATIONS
title(create(x, y, l, h, t)) = t
xpos(create(x, y, l, h, t)) = x
ypos(create(x, y, l, h, t)) = y
width(create(x, y, l, h, t)) = l
height(create(x, y, l, h, t)) = h
eqWin(v, w) = title(v) == title(w)
inWin(x, y, w) =
x >= xpos(w) AND
x <= xpos(w) + width(w) AND
y >= ypos(w) AND
y <= ypos(w) + height(w)
contains(a, b, c, d, w) =
inWin(a, b, w) AND inWin(a + c, b, w) AND
inWin(a, b + d, w) AND inWin(a + c, b + d, w)
overlap(v, w) =
((xpos(w) <= xpos(v) AND
xpos(w) + width(w) >= xpos(v)) OR
(xpos(v) <= xpos(w) AND
xpos(v) + width(v) >= xpos(w)))
AND
((ypos(w) <= ypos(v) AND
ypos(w) + height(w) >= ypos(v)) OR
(ypos(v) <= ypos(w) AND
ypos(v) + height(v) >= ypos(w)))
move(create(x, y, l, h, t), a, b) =
create(x + a, y + b, l, h, t)
381
resize(create(x, y, l, h, t), a, b) =
create(x, y, l + a, h + b, t)
382
ALGEBRA ScreenAlg USES WindowAlg, BoolAlg,
NatAlg, StringAlg
SORTS Screen, Window, Nat, Bool, String
OPERATIONS
emptyscreen: Screen
openwindow: Window, Screen Screen
deletewindow: Window, Screen Screen
popwindow: Window, Screen Screen
movewindow: Window, Nat, Nat, Screen Screen
resizewindow: Window, Nat, Nat, Screen Screen
isvisible: Window, Nat, Nat, Nat, Nat, Screen Bool
EQUATIONS
isvisible(w, a, b, c, d, emptyscreen) = error
isvisible(w, a, b, c, d, openwindow(v, s)) =
IF eqWin(v, w) THEN
IF contains(a, b, c, d, w) THEN true ELSE error
ELSE NOT overlap(create(a, b, c, d, ""), v)
AND isvisible(w, a, b, c, d, s)
deletewindow(w, emptyscreen) = error
deletewindow(w, openwindow(v, s)) =
IF eqWin(v, w) THEN s
ELSE openwindow(v, deletewindow(w, s))
popwindow(w, s) = openwindow(w, deletewindow(w, s))
movewindow(w, emptyscreen) = error
movewindow(w, a, b, openwindow(v, s)) =
IF eqWin(v, w) THEN openwindow(move(w, a, b),
deletewindow(w, s))
ELSE openwindow(v, movewindow(w, s))
resizewindow(w, emptyscreen) = error
resizewindow(w, a, b, openwindow(v, s)) =
IF eqWin(v, w)
THEN openwindow(resize(w, a, b),
deletewindow(w, s))
ELSE openwindow(v, resizewindow(w, s))
Ubung. Modizieren Sie popwindow so, da ein Fenster, das vollst andig sichtbar ist, durch
popwindow ganz nach hinten geschoben wird.
383
16.7 Spezikation mit Pr adikaten und Regeln
Bei der Spezikation mit Pr adikaten und Regeln werden Pr adikate zur Beschreibung von Zust anden
und Ereignissen festgelegt.
Pr adikate werden uber Variablen/Eingabedaten des zu spezizierenden Systems deniert.
F ur Realzeitsysteme k onnen Pr adikate auch von der Zeit abh angen.
Pr adikate m ussen nicht formal deniert sein.
Das Systemverhalten wird durch Angabe von Regeln (Implikationen) beschrieben.
Beispiel: a, b, c seien Variablen, x eine Eingabe; p(a, b, c), q(a, b, c) seien Zust ande, e(x, y) Er-
eignis.
Regel:
p(a, b, c) e(a, x) q(a, b, c)
Im Grunde spezielle Form von Automaten: die zustandsbeschreibenden Pr adikate beschreiben
die Zustandsmenge; ereignisbeschreibende Pr adikate beschreiben Zustands uberg ange.
Manchmal Abweichungen von dieser Regelform, z.B. sekund are
Uberg ange:
p(a, b, c) e(a, x) e(b, y)
384
16.7.1 Fallstudie: Fahrstuhlsteuerung
Es gibt n Fahrst uhle und m Stockwerke.
In jedem Stockwerk gibt es zwei Kn opfe, um den Fahrstuhl aufw arts oder abw arts zu rufen.
In jedem Fahrstuhl gibt es m Kn opfe zum Anw ahlen von Fahrzielen (Stockwerken).
Pr adikate zur Beschreibung von Zust anden
Alle Zust ande gelten in zusammenh angenden Zeitintervallen.
standing(E, F, T
1
, T
2
) wobei E [1..n], F [1..m], T
2
> T
1
t
0
Im Zeitintervall [T
1
, T
2
[ steht Fahrstuhl E in Stockwerk F.
moving(E, F, D, T
1
, T
2
) wobei E [1..n], F [1..m],
D up, down, T
2
> T
1
t
0
Im Zeitintervall [T
1
, T
2
[ bewegt sich Fahrstuhl E in Richtung D; zuletzt wurde Stockwerk
F passiert.
list(E, L, T
1
, T
2
) wobei E [1..n], L [1..m]
, T
2
> T
1
t
0
Im Zeitintervall [T
1
, T
2
[ gilt f ur Fahrstuhl E die Zielliste L.
Zustandsraum
_
(t, l) [t = standing(E, F, T
1
, T
2
) t = moving(E, F, D, T
1
, T
2
),
l = list(E, L, T
1
, T
2
),
D up, down,
E [1..n],
F [1..m],
L [1..m]
,
T
2
> T
1
R
+
0
_
385
Pr adikate zur Beschreibung von Ereignissen
Alle Ereignisse geschehen zu einem denierten Zeitpunkt T.
arrival(E, F, T) wobei E [1..n], F [1..m], T t
0
Fahrstuhl E kommt zur Zeit T in Stockwerk F an. t
0
ist die Startzeit des Systems; Zeiten
sind reelle Zahlen
departure(E, F, D, T) wobei E [1..n], F [1..m], D up, down, T t
0
E verl at zum Zeitpunkt T Stockwerk F in Richtung D
stop(E, F, T) wobei E [1..n], F [1..m], T t
0
E h alt zur Zeit T in Stockwerk F an
newlist(E, L, T) wobei E [1..n], L [1..m]
, T t
0
E bekommt zur Zeit T von der Steuerung eine neue Zielliste L zugewiesen
call(F, D, T) wobei F [1..m], D up, down, T t
0
Zur Zeit T wurde von F ein Fahrstuhl in Richtung D gerufen
request(E, F, T) wobei F [1..m], E [1..n], T t
0
Zur Zeit T wurde im Fahrstuhl E Stockwerk F gedr uckt
386
Regeln uber Zust ande und Ereignisse
1. Ein Fahrstuhl h alt an einem Stockwerk nicht an, wenn keiner ein-/aussteigen will und noch
andere Auftr age in der Liste stehen:
(a) arrival(E, F, T
a
) list(E, L, T, T
a
) L ,= ) head(L) > F
departure(E, F, up, T
a
)
(b) arrival(E, F, T
a
) list(E, L, T, T
a
) L ,= ) head(L) < F
departure(E, F, down, T
a
)
2. Will jedoch jemand an einem Stock ein-/aussteigen, an dem der Fahrstuhl gerade vor-
beif ahrt, so h alt der Fahrstuhl an:
arrival(E, F, T
a
) list(E, L, T, T
a
) L ,= ) head(L) = F stop(E, F, T
a
)
3. Wenn ein Fahrstuhl keine Auftr age mehr hat, h alt er am n achsten Stockwerk an:
arrival(E, F, T
a
) list(E, L, T, T
a
) L = ) stop(E, F, T
a
)
4. Ein gerade angehaltener Fahrstuhl mit nichtleerer Auftragsliste f ahrt los, nachdem das
Ein-/Aussteigen beendet ist. t
s
sei die (vereinfachend konstant angenommene) Dauer
des Ein-/Aussteigens:
(a) stop(E, F, T
a
) list(E, L, T, T
a
+ t
s
) L ,= ) head(L) > F
departure(E, F, up, T
a
+ t
s
)
(b) stop(E, F, T
a
) list(E, L, T, T
a
+ t
s
) L ,= ) head(L) < F
departure(E, F, down, T
a
+ t
s
)
5. Ein Fahrstuhl mit leerer Zielliste f ahrt los, sobald er neue Ziele bekommt:
(a) stop(E, F, T
a
) list(E, L
1
, T
a
+ t
s
, T
p
) L
1
= )
T
p
> T
a
+ t
s
list(E, L
2
, T
p
, T) L
2
,= ) head(L
2
) > F
departure(E, F, up, T
p
)
(b) stop(E, F, T
a
) list(E, L
1
, T
a
+ t
s
, T
p
) L
1
= )
T
p
> T
a
+ t
s
list(E, L
2
, T
p
, T) L
2
,= ) head(L
2
) < F
departure(E, F, down, T
p
)
6. t sei die Zeit, die f ur die Fahrt von einem Stock zum n achsten ben otigt wird. Wenn ein
Fahrstuhl in einem Stock losgefahren ist, kommt er also t sp ater im n achsten Stock an:
(a) departure(E, F, up, T) arrival(E, F + 1, T + t)
(b) departure(E, F, down, T) arrival(E, F 1, T + t)
7. Wenn ein Fahrstuhl angehalten hat, bleibt er mindestens f ur die Zeit t
s
stehen:
stop(E, F, T) standing(E, F, T, T + t
s
)
8. Wenn dann die Auftragsliste immer noch leer ist, bleibt er weiter stehen, bis eine neue
Auftragsliste kommt:
387
stop(E, F, T
s
)list(E, L, T
s
, T
s
+t
s
)L = )T > T
s
+t
s
standing(E, F, T
s
, T)
9. Wenn ein Fahrstuhl losgefahren ist, bleibt dieser Zustand mindestens f ur die Zeit t be-
stehen:
departure(E, F, D, T) moving(E, F, D, T, T + t)
10. Wenn ein Zustand in einem Zeitintervall besteht, so besteht er auch in jedem Teilintervall:
(a) standing(E, F, T
1
, T
2
), T
3
> T
1
, T
4
< T
2
standing(E, F, T
3
, T
4
)
(b) moving(E, F, D, T
1
, T
2
), T
3
> T
1
, T
4
< T
2
moving(E, F, D, T
3
, T
4
)
(c) list(E, L, T
1
, T
2
), T
3
> T
1
, T
4
< T
2
list(E, L, T
3
, T
4
)
388
Steuerregeln
1. Wenn ein Ziel bedient ist, wird es aus der Auftragsliste gestrichen:
arrival(E, F, T
a
) list(E, L, T, T
a
) F = head(L)
newlist(E, tail(L), T
a
)
2. Wenn im Fahrstuhl ein Zielknopf gedr uckt wird, so wird das Ziel sofort in die Auftragsliste
des Fahrstuhls einsortiert:
(a) an die passende Stelle, wenn der Fahrstuhl bereits in die richtige Richtung f ahrt
(b) sonst ans Ende der Liste
request(E, F, T
R
) standing(E, F, T
a
, T
R
) list(E, L, T
a
, T
R
)
newlist(E, insert(L, F, E), T
R
)
, T
2
) list(E, L, T
1
, T
3
)
Ubung. In den Kn opfen sind Lampen angebracht. Eine Fahrstuhlknopflampe leuchtet, wenn das
Stockwerk in der Auftragsliste des Fahrstuhl ist. Eine Stockwerkknopflampe
Abw arts leuchtet, wenn es einen Fahrstuhl gibt, dessen Auftragsliste das Stockwerk enth alt.
Geben Sie Zust ande, Ereignisse und Regeln zum Ein- und Ausschalten dieser Lampen an!
389
16.8 Checkliste: Feinentwurf
Der Feinentwurf (Spezikation) im Rahmen des Software-Entwicklungs-Praktikums wird an-
hand der folgenden Anforderungen beurteilt.
Ist die Spezikation vollst andig? Jede offentliche Methode mu beschrieben sein.
Ist die Spezikation widerspruchsfrei? Widerspr uche m ussen rechtzeitig erkannt und
aufgel ost werden.
Sind die Methoden gut dokumentiert?
Methoden m ussen insofern beschrieben sein, da ihre Funktionsweise deutlich wird. Hier-
zu geh ort eine Beschreibung aller Parameter, des R uckgabewertes und ggf. Seiteneffekte.
Oft braucht man nicht mehr als einen Satz:
sum(x, y) liefert die Summe von x und y.
Decken die Testf alle die Methoden ab? F ur solche Klassen, deren Methoden sich auto-
matisch aufrufen lassen, sollen Testf alle angegeben werden, die
die Methoden der Klasse abdecken (d.h. jede Methode sollte in wenigstens einem
Testfall aufgerufen werden) und
Testf alle aus dem Pichtenheft nachbilden.
Die Testf alle k onnen passend f ur JUnit oder in freier Form angegeben werden Hauptsa-
che, sie sind automatisch ausf uhrbar.
Sind die Testf alle aus dem Pichtenheft nachgebildet? Da die Testf alle aus dem Pich-
tenheft ohnehin ausgef uhrt werden m ussen, sollen sie bereits im Feinentwurf ausgearbeitet
werden.
Sind Testf alle aus dem Pichtenheft nicht ausgearbeitet, ist dies zu dokumentieren und zu
begr unden.
390
Kapitel 17
Qualit atssicherung
In Kapitel 4 haben wir allgemeine Qualit atsanforderungen f ur Software kennengelernt. Es gen ugt
nicht, Qualit atsanforderungen aufzustellen; genauso wichtig ist es, sicherzustellen, da diese
Forderungen auch erreicht werden.
391
17.1 Grundbegriffe der Qualit atssicherung
1
Die Manahmen zur Erf ullung der Qualit atsanforderungen werden unter zwei Begriffen zusam-
mengefat:
Qualit atsmanagement: managementbezogene Manahmen
Qualit atssicherung: technische Manahmen
17.1.1 Manahmen und Verfahren
Die Manahmen des Qualit atsmanagements lassen sich unterteilen in:
Konstruktive Qualit atsmanagement-Manahmen
sind Methoden, Sprachen, Werkzeuge, Richtlinien, Standards, die a priori f ur bestimmte
Eigenschaften des Produkts sorgen.
Hierzu geh oren produktorientierte Manahmen, etwa
Gliederungsschema f ur Pichtenhefte
Einsatz von Programmiersprachen mit statischer Typpr ufung
Einsatz von blockstrukturierten Programmiersprachen
wie auch prozeorientierte Manahmen, etwa
Richtlinien f ur den Entwicklungsproze
Werkzeuge f ur die Versionskontrolle
Analytische Qualit atsmanagement-Manahmen
sind diagnostische Manahmen, die die Qualit at der Produkte bewerten (per se also keine
Qualit at bringen).
Analysierende Verfahren sammeln Informationen uber den Pr ufling, z.B.
Programmverikation
Programminspektion
Komplexit atsmessung
Testende Verfahren f uhren den Pr ufling mit Eingaben aus. Beispiele:
Dynamischer Test
Symbolischer Test
1
Nach Balzert, Lehrbuch der Software-Technik
392
17.1.2 Grundprinzipien
Prinzip der unabh angigen Qualit atszielbestimmung
Jedes Software-Produkt soll nach seiner Fertigstellung eine zuvor bestimmte Qualit at be-
sitzen unabh angig von Proze oder Produkt.
Kunden und Lieferanten sollen gemeinsam Qualitatsziel bestimmen
Ziel: Explizite und transparente Qualit atsbestimmung vor Entwicklungsbeginn.
Prinzip der quantitativen Qualit atssicherung
Ingenieursm aige Qualit atssicherung ist undenkbar ohne die Quantizierung von Soll-
und Ist-Werten. (Rombach)
Einsatz von Metriken zur Qualit atsbestimmung
Ziel: Qualit atssteigerung mebar machen.
Prinzip der maximalen konstruktiven Qualit atssicherung
Je fr uher ein Fehler entdeckt wird, desto kosteng unstiger kann er behoben werden
Siehe auch Kapitel 4: Kosten der sp aten Fehlerbehebung
Ziel: Fehler m ussen so fr uh wie m oglich erkannt und behoben werden
Prinzip der entwicklungsbegleitenden Qualit atssicherung
Jeder Schritt, jedes Dokument im Entwicklungsproze ist der Qualit atssicherung unter-
worfen.
Ziel: Qualit atssicherung in jedem Schritt der Software-Entwicklung
Prinzip der unabh angigen Qualit atssicherung
Qualit atssicherung.
393
17.2 Programminspektion
Wir konzentrieren uns zun achst auf analytische Manahmen der Qualit atssicherung.
Eine Programminspektion ist ein formales Verfahren, in dem ein Programm durch andere Perso-
nen als den Autor auf Probleme untersucht wird.
17.2.1 Vorgehensweise
Eine Inspektion wird durch den Autor ausgel ost, sein Produkt zu uberpr ufen. Dies ge-
schieht typischerweise zur Freigabe f ur eine weitere Entwicklungsaktivit at.
Das Programm wird von mehreren Gutachtern beurteilt, wobei jeder Gutachter sich auf
einen oder mehrere Aspekte konzentriert.
Jeder Gutachter pr uft das Produkt anhand von Referenz-Dokumenten (etwa die Spezika-
tion) und notiert Erkenntnisse
In einer gemeinsamen Sitzung aller Gutachter mit einem ausgebildeten Moderator werden
gefundene und neu entdeckte Fehler protokolliert.
L osungen werden nicht diskutiert.
Ergebnis ist ein formalisiertes Inspektionsprotokoll mit Fehlerklassizierung
Auerdem werden Statistiken (Inspektionsmetriken) uber die Fehlerh augkeit erstellt, die
zur Verbesserung des Entwicklungsproze dienen
Der Autor uberarbeitet das Produkt anhand der neuen Erkenntnisse.
Der Moderator gibt das Produkt frei oder weist es zur uck
Der Inspektionsaufwand (individuelle Pr ufzeiten, Zeit f ur die gemeinsame Sitzung) mu von
vorneherein eingeplant sein
Inspektionen haben hohe Priorit at; d.h. sie sind kurzfristig einzuberufen
Inspektionsergebnisse d urfen nicht zur Beurteilung von Mitarbeitern eingesetzt werden
Vorgesetzte und Zuh orer d urfen an den Inspektionen nicht teilnehmen
394
17.2.2 Empirische Erkenntnisse
Pr ufaufwand liegt bei 15 bis 20% des Erstellungsaufwands
60 bis 70% der Fehler k onnen in einem Dokument gefunden werden
Nettonutzen bei 20% in der Entwicklung, 30% in der Wartung
Der Return on investment ist bei Inspektionen wesentlich besser als bei anderen Investitionen.
(Balzert)
17.2.3 Varianten der Programminspektion
Ein Review ist eine weniger formale manuelle Pr ufmethode (kein denierter Ablauf, informales
Inspektionsprotokoll).
Nutzen bei Fehlersuche ahnlich wie bei formalen Inspektionen
Verbesserungen im Entwicklungsproze nur indirekt
Ein Walkthrough ist eine weiter abgeschw achte Form, in der der Autor das Pr ufobjekt Schritt f ur
Schritt vorstellt. Die Gutachter stellen spontane Fragen, und versuchen so, Probleme zu identi-
zieren.
Geringer Aufwand
aber wesentlich schlechterer Nutzen
geeignet f ur
unkritische Dokumente
395
17.3 Pair Programming
Impair programming (Paar-Programmierung) arbeiten zwei Programmier Seite an Seite an einem
Rechner, um Programme zu entwerfen, implementieren und zu testen.
Ein Programmierer
f ahrt (h alt die Tastatur oder macht Notizen), der andere ist
Beifahrer
(begutachtet die Arbeit). Der Beifahrer nimmt aktiv teil am Geschehen. Diese Rollen werden
kontinuierlich gewechselt.
Durch das kontinuierliche Begutachten werden Fehler und Alternativen fr uhestm oglich erkannt
Kontinuierliches Review-Verfahren!
17.3.1 Ergebnisse
Erste Studien
2
zeigen, da sich der doppelte Personalaufwand auszahlt. Paare . . .
. . . ben otigen einen 100% h oheren Personalaufwand
. . . reduzieren die Codierungszeit hingegen um 4050%
. . . verbessern die Codequalit at (z.B. 94,4% bestandene Testf alle statt 78,1% bei Individu-
en)
17.3.2 Grundregeln
3
Beide Programmierer sind gleichermaen verantwortlich f ur ihre Arbeit.
Es gibt keine individuelle Schuld (kein
Ubertragung. . . )
Egoless programming ist hilfreich (der eigenen Schw achen bewut sein, keine uberm aige
Identizierung mit dem
eigenen Code)
Pausen einplanen! Pair programming ist anstrengend.
Pair programming ist Bestandteil des extreme programming (Abschnitt 3.7)
2
Williams, L., Kessler, R., Cunningham, W., Jeffries, R., Strengthening the Case for Pair-Programming, IEEE
Software, Juli/August 2000. Verf ugbar uber http://www.pairprogramming.com/.
3
Williams, L. und Kessler, R., All I Ever Needed to Know about Pair Programming I Learned in Kindergarten,
Communications of the ACM, Mai 2000. Verf ugbar uber http://www.pairprogramming.com/.
396
17.4 Testen
Wir kommen nun zu den testenden Verfahren.
17.4.1 Grundbegriffe
Die analytische Qualit atssicherung st utzt sich im allgemeinen auf den Begriff Fehler ab.
Ein Fehler ist
jede Abweichung der tats achlichen Auspr agung eines Qualit atsmerkmals von der vorgese-
henen Soll-Auspr agung
jede Inkonsistenz zwischen Spezikation und Implementierung
jedes strukturelle Merkmal des Programmtextes, das ein fehlerhaftes Verhalten des Pro-
gramms verursacht (Liggesmeyer)
Ziel des Testens ist, durch gezielte Programmausf uhrung Fehler zu erkennen.
Program testing can be used to show the presence of bugs, but never to show their absence.
(Dijkstra)
Laufendes Beispiel
PROCEDURE countVowels(s: sentence; VAR count: integer);
(
*
Counts how many vowels occur in a sentence.
Sentences must be terminated by a dot.
*
)
VAR
i: integer;
BEGIN
count := 0;
i := 1;
WHILE s[i] # . DO
IF s[i]=a OR s[i]=e OR s[i]=i OR
s[i]=o OR s[i]=u
THEN
count := count + 1;
END;
i := i + 1;
END;
END countVowels;
.
.
.
countVowels(this is a test., count);
397
17.4.2 Typische Softwarefehler
4
Fehler k onnen folgendermaen klassiziert werden:
Berechnungsfehler
Komponente berechnet falsche Funktion
z.B. Verwendung falscher Variablen, Konstanten oder Operatoren
Sehr beliebt: Konvertierungsfehler in FORTRAN oder PL/I
In FORTRAN sind Variablen, die mit I, J, oder K beginnen, implizit als Integer-Variablen
deklariert.
In der Steuerungssoftware der Raumsonde Mariner-IV hatte jemand vergessen, eine Real-
Variable zu deklarieren, deren Name mit I anng. Dadurch nahmder FORTRAN-Compiler
automatisch den Typ Integer f ur die Variable an und f ugte automatisch Konvertierungsope-
rationen ein. Es gab schreckliche Rundungsfehler, und die Sonde og am Mars vorbei.
Schnittstellenfehler
(syntaktische oder) semantische Inkonsistenz zwischen Aufruf und Denition einer Kom-
ponente
z.B.
Ubergabe falscher Parameter
Sehr beliebt: Vorbedingung einer Funktion wird nicht eingehalten
Kontrollufehler
Ausf uhrung eines falschen Programmpfades
z.B. Vertauschung von Anweisungen, falsche Kontrollbedingungen
Sehr beliebt: off by one-Fehler: Schleife wird einmal zu oft oder einmal zuwenig durchlau-
fen
Initialisierungsfehler
Falsche oder fehlende Initialisierung
Sehr beliebt: Zugriff auf nicht initialisierte Variablen
Datenufehler
Falsche Zugriffe auf Variablen und Datenstrukturen
z.B. falsche Arrayindizierung, Zuweisung an die falsche Variable
Sehr beliebt: Pointerfehler, z.B. Zugriff mit NIL-Pointer und oder Zugriff auf bereits frei-
gegebene Objekte
Auerdem Speicherfehler: doppelte Freigabe oder gar keine Freigabe (memory leak)
4
nach: V. R. Basili, B. T. Perricone: Software Errors and Complexity: An Empirical Investigation, CACM 27(1),
1984, S. 42-52.
398
Einige Fehler
PROCEDURE countVowels(s: sentence; VAR count: integer);
(
*
Counts how many vowels occur in a sentence.
Sentences must be terminated by a dot.
*
)
VAR
i: integer;
BEGIN
count := 0;
(
*
Initialisierungsfehler - i ist nicht initialisiert
*
)
WHILE s[i] # . DO
IF s[i]=a OR s[i]=i OR
s[i]=o OR s[i]=u
(
*
Kontrollflufehler - keine Prufung auf e
*
)
THEN
count := count + 2;
(
*
Berechnungsfehler - count wird zuviel erhoht
*
)
END;
count := i + 1;
(
*
Datenflufehler - Zugriff auf i statt auf count
*
)
END;
END countVowels;
.
.
.
countVowels(to be ... or not to be., count);
(
*
Schnittstellenfehler - Punkt vor dem Ende von s
*
)
399
17.4.3 Errors, Faults und Failures
Das deutsche Wort Fehler spiegelt die verschiedenen Begriffsbedeutungen nicht ausreichend
wieder.
Im Englischen wird daher unterschieden zwischen:
error: Eigenschaft des Quelltextes
fault: Falscher Zwischenzustand bei der Berechnung
failure: Von auen beobachtbares Symptom eines Fehlers
Zwischen error, fault und failure gelten folgende Beziehungen:
Ein Fehlersymptom ist immer Folge eines falschen Berechnungszustandes
Ein falscher Berechnungszustand tritt nur auf, wenn das Programm einen Fehler enth alt.
Kurz: failure fault error
Die Umkehrungen gelten nicht immer, d.h. es gibt Errors, die sich nicht als Failures manifestie-
ren.
Dies ist das Kernproblem des Testens!
Beispiel Berechnung des Maximums dreier Zahlen:
PROCEDURE max3(x, y, z: integer): integer
IF x > y THEN
max3 := x
ELSE
max3 := max(y, z)
ENDIF
END max3;
failure: max3(5, 2, 9) liefert 5
fault: max3 hat den Wert 5
error: statt max3 := x mu es max3 := max(x, z) heien
400
17.4.4 Testproze
Der Testproze wird in f unf Stufen unterteilt
5
:
Der Testproze ist Teil des Wasserfall-Modells
5
nach Sommerville, Software Engineering
401
Komponenten- und Modultest
Test jeder Funktion (jedes Moduls) gegen die Spezikation
Erfolgt f ur jede Funktion (jedes Modul) getrennt (stand-alone testing)
Daher Testrahmen notwendig, der lauff ahige Umgebung schafft:
Platzhalter (Dummies, stubs) simulieren modulexterne Komponenten (z.B. impor-
tierte Prozeduren)
Testtreiber (drivers) ubernehmen die Versorgung von auen (z.B. Initialisierung, Auf-
ruf mit g ultigen Parametern)
Subsystemtest
Insbesondere
Uberpr ufung der Schnittstellen
Integrationstest
Test des kompletten Systems (im Hause)
Umfat auch
Uberpr ufung nicht-funktionaler Eigenschaften (z.B. Performance, Bedien-
barkeit) und Stress testing (
im
laufenden Betrieb) getestet
Beta-Test durch ausgew ahlte Kunden, die Fehler zur uckmelden
Organisatorische und psychologische Faustregeln:
Validierung mu so fr uh wie m oglich erfolgen
Denition eines Abbruchkriteriums bzw. Testg utemaes
Testf alle zielgerichtet entwerfen und dokumentieren (Testplan)
Testen ist destruktiver Proze, Ziel ist Fehlernachweis
Implementierer nicht (alleiniger) Tester
402
17.4.5 Teststrategien
Top-down testing
Test beginnt mit den Steuerungsmoduln
Designfehler werden fr uh entdeckt
Ausgeteste Teilsysteme fr uh verf ugbar, insbesondere bei Zweigintegration (depth rst in-
tegration )
Hoher Aufwand f ur Implementierung der Platzhalter
Aufwendige Testfalldenition
Bottom-up testing
Test beginnt mit Implementierungen der Basisklassen (= Klassen, die keine weiteren Dien-
ste ben otigen)
Designfehler werden sp at entdeckt
Daher Kombination mit prototyping sinnvoll
Geringer Aufwand f ur Implementierung der Testtreiber
Einfache Testfalldenition
Bottom-up / Top-down testing sind komplement are Verfahren und werden in der Praxis h aug
kombiniert (sandwich testing).
Inkrementelles Testen
Problem:
Ubersicht:
405
17.5.1 Funktionale Testverfahren
Funktionale Testverfahren testen gegen die Spezikation und lassen die interne Programmstruk-
tur unber ucksichtigt. Sie verlangen, da die spezizierte Funktionalit at vollst andig (und nat urlich
spezikationstreu) implementiert ist (
Funktions uberdeckung).
Komplement ar zu white-box-Verfahren
Ben otigen vollst andige und widerspruchsfreie Spezikation
Problem: Testvollst andigkeit schwierig zu messen
Einfachste Auspr agung: Zufallstest F uttern des Programms mit zuf alligen Werten
Funktionale Verfahren ben otigen ein Orakel:
Das Orakel pr uft, ob ein vom Pr uing errechnetes Ergebnis korrekt im Hinblick auf die
Spezikation ist
Da dies i.a. unentscheidbar ist, spielt meist der Mensch die Rolle des Orakels
406
Funktionale
Aquivalenzklassenbildung
Wertebereiche von Ein- und Ausgaben werden in
Aquivalenzklassen eingeteilt
Bildung der
Aquivalenzklassen nur an der Spezikation orientiert (
black box)
Uberdeckungstests).
Grundlage ist der Programmcode (
white box)
i=1
P
i
= 1
Sei K
i
die Korrektheitswahrscheinlichkeit pro Klasse. Wir denieren
P
i
= P
_
x D
i
(x) korrekt
_
= P
i
K
i
P
i
= P
_
x D
i
(x) inkorrekt
_
= P
i
(1 K
i
)
Die Gesamtkorrektheitswahrscheinlichkeit R() l at sich dann wie folgt berechnen:
R() = P
_
x D (x) korrekt
_
=
s
i=1
P
_
x D
i
(x) korrekt
_
=
s
i=1
P
i
=
s
i=1
P
i
K
i
= 1
s
i=1
P
i
+
s
i=1
P
i
K
i
= 1
s
i=1
P
i
(1 K
i
)
= 1
s
i=1
P
i
Die K
i
sind unbekannt! Sie k onnen aber gesch atzt werden:
Nimm n
i
Eingabewerte aus Klasse D
i
; bestimme durch Testl aufe die Zahl der Fehler pro Klasse
f
i
, dann ist f
i
/n
i
1 K
i
, also
R() 1
s
i=1
f
i
n
i
P
i
.
417
Varianz der Fehlerwahrscheinlichkeit F() = 1 R():
2
s1
=
1
s 1
s
i=1
_
f
i
n
i
P
i
F()
_
2
F ur eine vorgegebene Gesamtzahl n =
s
i=1
n
i
von Tests wird die Varianz minimal, wenn
n
i
=
n
_
P
i
P
s
i=1
_
P
i
P
i
=
n P
i
_
K
i
(1 K
i
)
s
i=1
P
i
_
K
i
(1 K
i
)
Da die K
i
ja erst bestimmt werden sollen, mu man mit
geratenen n
i
anfangen; daraus K
i
sch atzen und hieraus verbesserte n
i
bestimmen
418
Verfahren zur Bestimmung der voraussichtlichen Fehlerkosten
Nicht alle Fehler sind gleich teuer!
verwende Fehlerkostenfunktion: f ur x D Fehlerkosten g(x)
Erwartete Fehlerkosten:
C() =
xD
p(x) g(x)
mit p(x) Wahrscheinlichkeit f ur Eingabe x
Problem: unendlich viele Testf alle.
Annahme: D kann so partitioniert werden, da die Kosten innerhalb Klasse D
i
konstant sind.
Sei P
i
= P(x D
i
), G
i
die Kosten der Klasse i, so ist
C() =
s
i=1
P
i
G
i
der Erwartungswert f ur die Gesamtkosten
Es ist realistisch, nur eine endliche Zahl von
Kostenklassen anzunehmen
Allerdings ist es in der Praxis fast unm oglich, die P
i
zu bestimmen
Zusammen mit dem Lastprol kann eine Verteilung der Testwerte bestimmt werden, die die
Kosten korrekt sch atzt und minimale Varianz hat
6
6
W. Gutjahr: Optimal test distribution for failure cost estimation, IEEE Transactions on Software Engineering,
M arz 1995
419
Zuverl assigkeitsvorhersage
Nach jeder
Anderung oder Fehlerkorrektur mu die komplette Testsuite erneut durchgespielt
werden (automatisch)
Zeitliche Entwicklung der Zuverl assigkeit nach
Anderungen oder Fehlerkorrekturen kann in eine
Kurve eingetragen werden
Interpolation erlaubt Prognose, wann bestimmte Zuverl assigkeit erreicht ist
Beispiel
7
:
7
aus Sommerville, Software Engineering
420
17.5.5 Diversizierende Testverfahren
Diversizierende Testverfahren betrachten verschiedene Programmversionen bzw. -Implementierungen
und erwarten, da beobachtbare Abweichungen zwischen Original und Varianten erzeugt wer-
den.
Varianten entstehen
1. aus der Spezikation durch Mehrfachimplementierung (N-Versionen-Programmierung)
2. aus dem Programm durch systematische Anwendung von Transformationsregeln (Mutati-
onstesten)
Werden keine Verhaltensabweichungen aufgedeckt, so wei man, da
die Zahl der Testf alle nicht ausreichend war Validierung der Testdaten
oder die Varianten sich tats achlich im Verhalten nicht unterscheiden
421
N-Versionen-Programmierung
Auch back-to-back testing genannt
Programm wird nach gegebener Spezikation von N getrennten Teams implementiert und
getestet (N 3)
Die Teams d urfen nicht in Kontakt stehen
Hardware u.U. gleichfalls N-fach beschafft
Die N Versionen laufen parallel. Bei nicht identischen Resultaten ndet Mehrheitsabstim-
mung statt (u.u. Komparator-Hardware)
Annahme: Programmfehler in den Varianten sind statistisch unabh angig
Probleme der N-Versionen-Programmierung:
N-fache Kosten
Grundlegende Annahme nicht gew ahrleistet:
Fehler in der Spezikation werden von allen Programmierern gleich (falsch) imple-
mentiert
systematische Fehler: z.B. alle Implementierer haben zuf allig denselben falschen Al-
gorithmus gelernt
Untersuchungen haben gezeigt, da Programmfehler eben nicht statistisch unabh angig
sind
422
Mutationstesten
8
Grundideen: Programme sind
Der Testdatensatz hat nur 60% aller Mutanten gekillt. Wir brauchen also
noch mehr Testf alle
Fehlermodellierung durch Mutationsoperatoren
beschreiben Erzeugung semantisch ver anderter, aber syntaktisch korrekter Programmver-
sionen
f ur jede Fehlerklasse spezielle Operatoren
jeder Mutant enth alt nur eine Abweichung
Vorteile:
Verfahren zur Beurteilung von Testdatens atzen
weitgehend automatisierbar
explizite Fehlerorientierung
Modellierung anderer Verfahren m oglich (z.B. Anweisungs uberdeckung, special value te-
sting)
Nachteile:
es werden nur
Andern von logischen und relationalen Operatoren (AND statt OR, statt <)
Aufruf anderer Prozeduren
L oschen von Anweisungen
Einf ugen von HALT-Anweisungen
Initialisierungsfehler
hineingetestet sondern
hineinentwickelt
Sehr zuverl assige Software bei kaum erh ohten Entwicklungskosten
In groen Projekten (IBM, NASA) erfolgreich eingesetzt
10
H. W. Mills. M. Dyer, R. Linger: Cleanroom Software Engineering, IEEE Software 4(5), S. 19-25, 1987
11
R. W. Selby, V. R. Basili, T. Baker: Cleanroom software development: An empirical evaluation, IEEE Trans.
Software Eng. SE-13, S. 1027-1037, 1987.
426
17.7 Komplexit atsmae (Software-Metriken)
Ein Komplexit atsma ist eine Abbildung
: PROGRAM /
von Programmen in einen beliebigen metrischen Raum /( ublicherweise N oder R). Die De-
nition eines Maes ist nur sinnvoll, wenn ein Homomorphismus ist.
F alschlich auch als Metriken bezeichnet
Komplexit atsmae sind der Versuch, relevante Eigenschaften eines Programms auf eine Zahl zu
verdichten
Begrenzte Aussagef ahigkeit:
unklare Denitionen
Verwendung empirischer Konstanten
logarithmische Gl attung
keine Aussage uber Korrektheit
427
17.7.1 Lines of code (LOC)
LOC(P) = [N[
[N[ Anzahl der Knoten im Kontrollugraphen G von P
unver andert bei
Andern / Einf ugen von Kanten
Beispiel: LOC(countVowels) = 7
17.7.2 Zyklomatische Zahl
12
Sei [E[ Anzahl der Kanten in G,
p Anzahl der Zusammenhangskomponenten von G (i.a. p = 1)
ZZ(P) = [E[ [N[ + 2p
beruht auf dem Satz von Euler zur Berechnung der Zahl der Gebiete von planaren Graphen
mit die Anzahl der unabh angigen Pfade von P
vielfach modiziert
unver andert bei Einf ugen von Statements (Knoten/Kante-Paare) und
Andern von Kanten
Beispiel (vgl. Abbildung des Graphen): ZZ(countVowels) = 3
[E[ = 8, [N[ = 7
in GOTO-freien Programmen:
ZZ(P) = [IF/WHILE-Stmts[ + 1
(Zahl der Verzweigungen; vgl. CountVowels)
Regel von McCabe: ZZ(P) 10 (?)
12
T. J. McCabe: A Complexity Measure, in: IEEE Trans. Soft. Eng., SE-2(4), S.308-320, 1976.
428
17.7.3 Halstead-Mae
13
Basisgr oen:
n
1
, n
2
Anzahl der unterschiedlichen Operatoren bzw. Operanden
N
1
, N
2
Gesamtanzahl der Operatoren bzw. Operanden
Programmgr oe V (volume)
V = (N
1
+N
2
) log
2
(n
1
+n
2
)
Gr oe des Programms in Bits bei Bin arcodierung
Potentielle Programmgr oe V
= (2 +n
2
) log
2
(2 +n
2
)
n
1
= 2: Funktionsaufruf, Wertzuweisung
N
1
= n
1
, N
2
= n
2
: Implementierung minimaler L ange (n amlich ein Aufruf einer
[Bibliotheks]funktion und Ergebniszuweisung)
)
Ma f ur die Problemn ahe der Sprache
Aufwand E (effort)
E = V D
Bestimmung von n
1
interpretationsabh angig
Beispiel: countVowels
n
1
= 14, N
1
= 39
n
2
= 14, N
2
= 35
V = (35 + 49) log
2
(14 + 14) = 355.744
V
= (2 + 14) log
2
(2 + 14) = 64
D = 5.56
E = 1977.408
Aufwand E korreliert f ur mittelgroe Programme gut mit tats achlichem Wartungsaufwand
F ur groe Programme ungeignet, da Architekturaspekte nicht ber ucksichtigt werden
13
M. H. Halstead: Elements of Software Science, North-Holland, New York 1977.
429
17.8 Verbesserung der Prozequalit at
14
Wir kommen nun zu den konstruktiven Verfahren der Qualit atssicherung.
17.8.1 Qualit atssicherung mit ISO 9000
Das ISO 9000-Normenwerk legt f ur das Auftraggeber-Lieferantenverh altnis einen allgemeinen,
organisatorischen Rahmen zur Qualit atssicherung fest
Das ISO 9000-Zertikat eines Unternehmens bedeutet, da die eingesetzten Verfahren der ISO
9000-Norm entsprechen.
Wichtige Teile
ISO 9000-1 Allgemeine Einf uhrung und
Uberblick
ISO 9000-3 Anwendung von ISO 9001 auf Software
ISO 9001 Modelle der Qualit atssicherung in Design/Entwicklung, Produktion, Montage und
Kundendienst
ISO 9004 Verbesserung und Aufbau eines Qualit atsmanagement-Systems.
Dokumente
ISO 9000-3 f uhrt erforderliche Dokumente mitsamt ihren Inhalten auf:
Vertrag Auftraggeber-Lieferant u.a. Annahmekriterien, Problembehandlung,
T atigkeiten des Auftraggebers
Spezikation u.a. Anforderungen, Leistung, Ausfallsicherheit
Entwicklungsplan u.a. Zielfestlegung, Projektmittel, Entwicklungsphasen, Management, Pro-
jektplan
Qualit atssicherungsplan u.a. Qualit atsziele (in mebaren Gr oen), Vorgaben und Ergebnisse
der Entwicklungsphasen, Testmanahmen
Testplan u.a. Testf alle, Testdaten, Kriterien f ur Vollst andigkeit
Wartungsplan u.a. Umfang, Unterst utzung
Kongurationsmanagementplan u.a. Werkzeuge, Methoden
14
Nach Balzert, Lehrbuch der Software-Technik
430
T atigkeiten
ISO 9000-3 schreibt kein spezielles Vorgehensmodell vor, verlangt aber eine Reihe von un-
terst utzenden T atigkeiten:
Kongurationsmanagement Identikation und R uckverfolgbarkeit der
Anderungen, Lenkung
von
Anderungen, Statusberichte
Lenkung der Dokumente
Qualit atsaufzeichnungen
Messungen und Verbesserungen am Produkt und am Proze
Festlegung von Regeln, Praktiken und
Ubereinkommen f ur ein Qualit atssicherungsssytem
Nutzung von Werkzeugen und Techniken, um den Qualit atssicherungs-Leitfaden umzusetzen
Unterauftragsmanagement
Einf uhrung und Verwendung beigestellter Software-Produkte
Schulung aller Mitarbeiter, die qualit atsrelevante Tatigkeiten durchf uhren sowie Verfahren zur
Ermittlung des Schulungsbedarfs.
Vorsicht:
Normiert sind nur die betrieblichen Abl aufe
Der Einsatz von Qualit atssicherung ist noch keine Garantie f ur qualitativ hochwertige Pro-
dukte
431
Zertizierung
Software-Unternehmen, die ein Qualit atsmanagementsystem gem a diesem Normenwerk be-
sitzen, k onnen sich ein ISO 9001-Zertikat verleihen lassen, das die Qualit at der eingesetzten
Verfahren bescheinigt.
Alle betroffenen Bereiche eines Unternehmens werden von einer unabh angigen Zertizierungs-
stelle systematisch daraufhin beurteilt, ob die notwendigen Qualit atsmanagementmanahmen
festgelegt sind, ob sie wirksam sind, und ob sie nachweislich durchgef uhrt werden. Diese Unter-
suchung heit Qualit atsauditing und ndet in Form von Interviews statt.
Beispiel f ur Fragen eines Auditing:
Ist das Qualit atsmanagementsystemhinreichend schriftlich festgelegt und verst andlich dar-
gestellt?
Gibt es ein Qualit atsmanagement-Handbuch?
Welche erg anzenden Dokumente gibt es?
Besteht eine Verbindlichkeitserkl arung f ur das Qualit atsmanagement-Handbuch?
Wie werden die Mitarbeiter uber die sie betreffenden Regelungen informiert oder geschult?
Das Auditing mu j ahrlich erneuert werden.
Ein erteiltes Zertikat eignet sich gut f ur die Werbung
432
17.8.2 Totales Qualit atsmanagement (TQM)
Totales Qualit atsmanagement (TQM) ist ein umfassendes Konzept, das das gesamte Unterneh-
men mit allen Mitarbeitern in die Qualit atsverbesserung einbezieht.
Japanischer Ansatz
Qualit at aus der Sicht des Kunden ist das oberste Ziel
Die Software-Entwicklung ist eher kundengetrieben als technikgetrieben
Grundprinzipien des TQM:
Prinzip des Primats der Qualit at (Quality rst)
Jeder Mitarbeiter soll seine Arbeit beim ersten Mal und jedes Mal erneut wieder richtig
tun.
Qualit atsm angel werden sofort beseitigt: Ein Programmierer, der M angel am Entwurf fest-
stellt, soll die Entwicklung sofort stoppen k onnen.
Prinzip der Zust andigkeit aller Mitarbeiter
Jeder Mitarbeiter versteht Qualit at als integralen Bestandteil seiner Arbeit
Keine unabh angige Qualit atssicherungsabteilung
Prinzip der st andigen Verbesserung (Kaizen)
Motto:
keine erkannten
Fehler)
Erw unscht sind automatische Tests (z.B. JUnit) und systematische Tests (z.B.
Uberdeckungs-
tests).
Vergleiche auch Abschnitt 16.2 zu exemplarischer Spezikation.
440
Welche Integrationstests wurden durchgef uhrt?
Hierzu geh ort das Testen der im Pichtenheft aufgef uhrten Szenarien und die Beschrei-
bung der Ergebnisse.
17.9.3 Endg ultige Benutzeranleitung
Die endg ultige Benutzeranleitung basiert auf der vorl augen Benutzeranleitung aus dem Pich-
tenheft; sie beschreibt den Umgang mit der aktuellen Implementierung.
Abschnitt 9.7 enth alt eine
Ubersicht der Anforderungen.
Abbildungen des laufenden Programms sind erw unscht.
441
Kapitel 18
Arbeiten im Team
Wie in Kapitel 1 erl autert, ist Software-Engineering die Multi-Personen-Konstruktion von Multi-
Versionen-Software.
In diesem Kapitel wollen wir uns auf die besonderen Herausforderungen des Arbeitens in der
Gruppe konzentrieren, und zwar auf
Technische Aspekte, insbesondere Versionsverwaltung.
Organisations-Aspekte, insbesondere Fragen der Qualikation, der Produktivit at, und der
Teamorganisation.
442
18.1 Kongurationsmanagement
1
Wird Software im Team entwickelt, l at sie sich weitestgehend als Produkt einzelner Entwick-
lungsschritte beschreiben, die wir unter dem Begriff
Anderung zusammenfassen.
Eine
Anderung ist ein Entwicklungsschritt, der ein Dokument des Produkts erweitert, ver andert
oder k urzt.
Wir wollen nun Werkzeuge vorstellen, die diesen
Anderungsproze organisieren und kontrollie-
ren, was Gegenstand des Software-Kongurationsmanagements (SKM) ist.
Hauptziel von Kongurationsmanagement ist es, den Verlust von
Anderungen zu vermeiden.
Hierzu schreibt Tichy (1995):
Kongurationsmanagement wurde urspr unglich von der US-Raumfahrtindustrie in
der Mitte der f unfziger Jahre eingef uhrt.
Ein ernstes Problem zu dieser Zeit war, da Raumfahrzeuge w ahrend ihrer Entwick-
lung zahlreichen undokumentierten
Anderungen unterlagen eine Situation, wie sie
heute bei der Software-Entwicklung kaum anders ist.
Erschwerend kamdamals jedoch hinzu, da Raumfahrzeuge imTest normalerweise
vernichtet wurden sie st urzten ins Meer, vergl uhten in der Atmosph are, entkamen
ins All oder waren ohnehin daf ur bestimmt, sich zu zerst oren.
Das Ergebnis war, da nach einem erfolgreichen Test die Hersteller nicht in der La-
ge waren, eine Serienfertigung aufzunehmen oder auch nur einen Nachbau durch-
zuf uhren: Die Pl ane waren veraltet und der Prototyp mit allen
Anderungen verloren.
Um diesen Informationsverlust zu vermeiden, wurde Kongurationsmanagement er-
dacht.
1
Dieser Abschnitt basiert auf A. Zeller, J. Krinke: Programmierwerkzeuge, dpunkt-Verlag, Mai 2000. Kapitel 4
uber CVS ist als Leseprobe kostenlos verf ugbar unter http://www.dpunkt.de/buecher/3-932588-70-3.html
443
18.1.1 Anforderungen ans Kongurationsmanagement
Kongurationsmanagement mu folgende Anforderungen erf ullen:
Rekonstruktion
Koordination
Identikation
Rekonstruktion: Fr uhere Kongurationen m ussen zu jedemZeitpunkt wiederhergestellt werden
k onnen; eine Konguration ist dabei eine Menge von Software-Komponenten in bestimm-
ten Versionen.
Rekonstruktion ist einerseits wichtig, um
Anderungen zwischen fr uheren und neueren Ver-
sionen aufzuzeigen; andererseits, um den Code-Zustand bereits ausgelieferter Programme
f ur die Wartung nachbilden zu k onnen.
Koordination: Es mu sichergestellt werden, da
Anderungen von Entwicklern nicht versehent-
lich verlorengehen.
Dies bedeutet insbesondere das Aufl osen von Konikten, wenn mehrere Entwickler gleich-
zeitig eine Komponente bearbeiten m ochten.
Identikation: Es mu stets m oglich sein, einzelne Versionen und Komponenten eindeutig zu
identizieren, um damit die jeweils angewandten
Anderungen erkennen zu k onnen.
Dies bedingt die Vergabe von Kennungen f ur einzelne Versionen und Komponenten.
Schon in Ein-Personen-Projekten geh ort Kongurationsmanagement zu den Pichten des Ent-
wicklers.
In gr oeren Projekten ( 10 Personen) ist oft ein Entwickler hauptamtlich mit Kongurations-
management betraut.
Kongurationsmanagement auf Software wird in der Regel automatisiert:
RCS f ur kleine (1-Dateien-) Systeme und lokale Entwickler
CVS f ur groe Systeme und verteilte Entwickler
Clearcase oder Continuus f ur unternehmensweite Koordinierung
444
18.1.2 Rekonstruktion
In Software-Projekten wird Kongurationsmanagement mit Hilfe besonderer Werkzeuge reali-
siert.
Diese Werkzeuge stellen ein zentrales Archiv bereit, in dem alte und neue Versionen der Doku-
mente platzsparend abgelegt werden.
Der Platz wird gespart, indem nur die Unterschiede zwischen den einzelnen Versionen abgelegt
werden: beim Ablegen einer neuen Version werden nur die Zeilen (Zeichen) abgelegt, die neu
eingef ugt wurden.
Mit einer checkout-Operation kann man bestimmte Kongurationen aus dem Archiv in einen
individuellen Arbeitsbereich herauskopieren.
Beispiel: Kopieren aus einem CVS-Archiv:
anke$ cvs checkout petri
cvs checkout: Updating petri
U petri/Makefile
U petri/a.C
U petri/b.C
U petri/c.C
anke$
a.C
b.C c.C
a.C
c.C
checkout -r conf2 checkout -r conf1
a.C,v
b.C,v c.C,v
Arbeitsbereich CVS-Archiv Arbeitsbereich
1
Beim checkout kann man z.B. das Datum der gew unschten Version angeben und so beliebige
Kongurationen wiederherstellen.
Im linken Arbeitsbereich etwa wurde eine fr uhere Konguration ausgew ahlt, in der es die Datei
b.C noch nicht gab.
Alternativen zur Rekonstruktion:
Der Kunde soll gef alligst die neueste Software benutzen!
Ich wei auch nicht, warum es gestern noch lief. . .
445
18.1.3 Koordination
Jeder Entwickler erh alt seinen eigenen Arbeitsbereich, so da seine
Anderungen von anderen
Gutes Projektmanagement ist keine Garantie f ur das Gelingen, aber schlechtes Projektmana-
gement f uhrt unausweichlich zum Scheitern.
2
nach: H. Koontz, C. ODonnell, H. Weirich, Management, McGraw-Hill, New York, 1980.
3
Salopper ausgedr uckt ist Management die Kunst, andere Leute die Arbeit machen zu lassen.
448
Besonderheiten des Software-Managements
Die Besonderheiten des Produkts
lernen) fort.
Effektive Probleml osungsstrategien wie z.B. top-down-Zerlegung und strukturierte Programmie-
rung m ussen die Ged achtnisstruktur ber ucksichtigen:
top-down-Zerlegung erleichtert dem Kurzzeitged achtnis die Chunk-Organisation
strukturierter Kontrollu erm oglicht Konzentration auf einen Programmausschnitt.
verhindert
Information, sondern
Nur das Beste ist gut genug f ur uns. Jedes Teambraucht eine Herausforderung.
Mittelm aige Aufgaben nehmen den Ehrgeiz, eine herausragende Leistung zu bringen.
Niemand ist stolz, an einem
Schundprojekt zu arbeiten.
Kein Overengineering. Vergolden Sie keine Funktionen, nur weil es dem Team Spa macht.
Perfektionieren Sie das Notwendige.
Vielfalt. Gr oere Erfolgschancen, wenn Team vielf altig zusammengesetzt ist (z.B. M anner und
Frauen, Endanwender und Entwickler. . . ) Vergl. Abschnitt ??.
Persistenz.
verbannen Teams zeitweise in v ollige Isolation (Hotel, Ferienhaus).
Teamorientierte Mitarbeiter. . .
sind positiv zur Teamarbeit eingestellt.
sind Kritik- und Konikttolerant.
erkennen und respektieren die fachliche Qualikation und pers onliche Integrit at anderer.
verhalten sich partnerschaftlich.
k onnen widerspr uchliche und voneinander abweichende Informationen verarbeiten.
sind bereit, sich voll im Team zu engagieren.
sind mit sich selbst zufrieden.
Ein eingeschworenes Team erkennt man an:
Niedrige Fluktuationsrate
Ausgepr agtes Identikationsbewutsein
Freude an der Arbeit
Bewutsein einer Elitemannschaft
464
18.2.4 Produktivit at f ordern
10
Groe Produktivit atsunterschiede zwischen Software-Entwicklern:
Grundregeln:
Die besten Mitarbeiter sind 10 besser als die schlechtesten
Die besten Mitarbeiter sind 2,5 besser als der Durchschnitt
Die uberdurchschnittlichen Mitarbeiter ubertreffen die unterdurchschnittlichen Mitarbeiter
im Verh altnis 2:1.
Diese Regeln gelten f ur fast jede beliebige Leistungsmetrik (Zeit, Fehler. . . ).
10
Nach De Marco, Lister: Peopleware, 2nd ed., Dorset House, New York 1999
465
Relevante Faktoren
Ein Mitarbeiter ist um so produktiver
je ruhiger sein Arbeitsplatz (= je weniger er gest ort wird)
je besser die Privatsph are ist
je gr oer der Arbeitsplatz ist.
Ubersicht Umfrageergebnisse:
Arbeitsplatzfaktoren bestes Viertel schlechtestes Viertel
der Teilnehmer der Teilnehmer
1 Wieviel Arbeitsplatz steht 7m
2
4,1 m
2
Ihnen zur Verf ugung?
2 Ist es annehmbar ruhig? 57% ja 29% ja
3 Ist Ihre Privatsph are gewahrt? 62% ja 19% ja
4 K onnen Sie Ihr Telefon abstellen? 52% ja 10% ja
5 K onnen Sie Ihr Telefon umleiten? 76% ja 19% ja
6 Werden Sie oft von anderen 38% ja 76% ja
Personen grundlos gest ort?
466
Hintergrund
Um produktive Ingenieurarbeit zu erledigen, mu man
in Fahrt: Zustand tiefer, fast meditativer Versunkenheit
Man f uhlt eine leichte Euphorie und verliert das Zeitgef uhl
F ur diesen Zustand ben otigt man ca. 15 Minuten voller Konzentration
In diesem Zustand ist man besonders anf allig f ur St orungen
Ein Telefonanruf und die 15 Minuten Eintauchphase beginnen von vorne!
Konsequenzen
Abstellbare (oder gar keine) Telefone keine Lautsprecherdurchsagen
Einzelb uros (mit verschliebarer T ur) keine
Cubicles
Niedriger Ger auschpegel keine Groraumb uros
Musik kann zwar einen Ger auschpegel ubert onen, blockiert jedoch die rechte Gehirnh alfte, die
f ur Kreativit at zust andig ist
467
18.2.5 Kreativit at f ordern
Viele Aktivit aten der Software-Entwicklung erfordern ein hohes Ma an Kreativit at insbeson-
dere der Entwurf und die Fehlerbeseitigung.
Kreativit at ist die F ahigkeit, Wissen und Erfahrung aus verschiedenen Bereichen zu neuen L osun-
gen und Ideen zu verschmelzen, wobei verfestigte Denkmuster uberwunden werden.
Klassisches Brainstorming
11
Brainstorming ist eine spezielle Form einer Gruppensitzung, mit dem Ziel, Ideen und Gedanken
einer Gruppe frei ieen zu lassen und sie zu neuem zu kombinieren.
Regeln:
1. Freies und ungehemmtes Aussprechen von Gedanken; auch sinnlos erscheinende und phan-
tastische Einf alle sind erw unscht, da sie andere Teilnehmer inspirieren k onnen.
Alle Vorschl age an Tafel, Pinnwand oder Flipchart schreiben.
2. Die gemachten Vorschl age sind als Anregungen aufzunehmen und assoziativ weiterzuent-
wickeln.
Voraussetzung: Zuh oren und inhaltlich offen sein.
3. Kritik und Bewertung sind w ahrend der Sitzung verboten.
Keine Killerphrasen wie
Ubung f ur die Kontrahenten, vor den eigenen Argumenten die des Vorredners zusammen-
zufassen.
N achste Schritte. Hier werden wiederum konkrete, mebare Aktivit aten entschieden, die sp ater
(z.B. in der n achsten Sitzung) gepr uft werden k onnen.
Ergebnisse niederschreiben. Vergessen Sie nicht, die Ergebnisse (= Stand der Dinge und n achste
Schritte) in einem Protokoll festzuhalten.
Dies ist gew ohnlich Aufgabe des Protokollf uhrers (der auch identisch mit dem Moderator
sein kann).
Der Moderator sorgt daf ur, da alle Teilnehmer das Protokoll erhalten (um ggf. sp ater
Einspruch einzulegen).
470
Anhang A
Programmverstehen
Unter Programmverstehen (engl. program comprehension, auch reverse engineering) fat man
Techniken zusammen, die einem Programmierer das Verst andnis eines Programms erleichtern
sollen.
Programmverstehen wird eingesetzt f ur
Zertizierung des Programms (
// Vorbedingung
assert(x >= 0 && y >= 0);
while (x != y)
// Invariante
assert(x >= 0 && y >= 0);
if (x > y)
x -= y;
else
y -= x;
return x;
assert(tree ok(tree)); /
*
Vorbedingung
*
/
.
.
. /
*
Funktion
*
/
assert(tree ok(tree)); /
*
Nachbedingung
*
/
Auch fehlerhafte Zust ande in Systembibliotheken k onnen h aug per Invariante eingeengt wer-
den.
Beispiel: GNU malloc-Bibliothek Ist die Umgebungs-Variable MALLOC CHECK auf 2 gesetzt,
werden zur Laufzeit die wichtigsten Invarianten des Freispeichers gepr uft; bei Verletzung (z.B.
mehrfaches Freigeben desselben Speicherbereichs) wird das Programm abgebrochen.
480
Zeugen
Mit Zeugen kann man beweisen, da Berechnungen korrekt sind.
Beispiel: Wurzelberechnung mit Probe
double square root(double x)
y ist hier Zeuge f ur die Korrektheit von root, da y beweist, da root korrekt berechnet wurde.
Alternative: Doppelte Berechnung
double square root(double x)
Hier wird in y die Wurzel mit einem alternativen Verfahren berechnet; auch hier dient y als
Zeuge.
Probleme bei doppelten Berechnungen:
M oglichkeit systematischer Fehler gleiche (falsche) Annahmen aus einer Spezikation
Meist aufwendiger als Proben
Verfahren im Vergleich
Zusicherungen gelten als die beste Methode zum horizontalen Einengen, denn
sie k onnen stets zur Laufzeit gesichert werden
sie spielen gut mit automatischen Tests zusammen
481
sie dokumentieren Zustandsbedingungen
Nat urlich k onnen alle Verfahren gleichzeitig eingesetzt werden!
482
A.2.4 Zustand eingrenzen Vertikales Einengen
Ziel des vertikalen Einengens ist es, diejenigen Variablen(werte) ausndig zu machen, die rele-
vant f ur den ung ultigen Zustand sind also die Ursachen des ung ultigen Zustands.
Zustand i
.
.
.
...
Einengen des Zustands
irrelevant
relevant
Beispiel f ur Eingrenzen des Zustands:
Ein Zeiger p, der dereferenziert werden soll, hat den Wert NULL.
Das liegt daran, da der Zeiger kurz zuvor mit p = getpwnam(name) auf den Eintrag
aus der Benutzerdatenbank vom Benutzer name gesetzt wurde
Das liegt daran, da der Name name mit name = getenv("USER") aus der Umgebungs-
variable USER eingelesen wurde
Das liegt daran, da die Umgebungsvariable USER nicht gesetzt ist
So ergibt sich eine Ursache-Wirkungs-Kette von USER uber name zu p. Diese drei beteiligten
Variablen sind relevant; alle anderen nicht.
483
Problem beim Einengen: Programmzust ande sind gro!
Beispiel: Programmzustand des GNU-Compilers (gcc) mit 44.000 Variablen und ihren Verwei-
sen
Auf welche Teile des Zustands soll man sich konzentrieren?
Wichtig: Grundlegendes Wissen uber m ogliche Zusammenh ange des Programms.
484
Systematisches Einengen
Verfahren: Man w ahlt einen Zustand des Programms aus und teilt den Zustand per Teile und
Herrsche in die einzelnen Komponenten oder Subsysteme.
Uber diese Komponenten stellt man Hypothesen auf etwa, da ein Fehler sich in diesem Teil-
bereich manifestiert. Diese Hypothesen werden dann gepr uft best atigt oder widerlegt, um die
Fehlerursache einzugrenzen.
2. Hypothese
Mgliche Fehlerursachen 1. Hypothese aufstellen 1. Hypothese prfen
3. Hypothese 4. Hypothese ...
Allgemeines Vorgehen:
Wird eine Hypothese best atigt, wird sie weiter verfeinert
Wird eine Hypothese widerlegt, wird ihr Komplement untersucht
Kann eine Hypothese weder best atigt noch widerlegt werden, wird eine alternative Hypo-
these aufgestellt.
*
*
je nach Testausgang
Neue Hypothese
Hypothese prfen
485
Typische Hypothesen sind:
Werden Vor- und Nachbedingungen eingehalten?
Werden Invarianten uber Datenstrukturen eingehalten?
Stimmen die vorgefundenen Werte mit den erwarteten Werten uberein?
Werkzeuge: Zusicherungen, interaktive Debugger
Ist die Fehlerursache gefunden, mu durch einen weiteren Test gepr uft werden, ob die Korrektur
den Fehler behebt (Ausschlu-Hypothese:
int i, j;
int h = 1;
do
h = h
*
3 + 1;
while (h <= size);
do
h /= 3;
for (i = h; i < size; i++)
int v = a[i];
for (j = i; j >= h && a[j - h] > v; j -= h)
a[j] = a[j - h];
if (i != j)
a[j] = v;
while (h != 1);
Hauptfunktion main
int main(int argc, char
*
argv[])
int
*
a;
int i;
a = (int
*
)malloc((argc - 1)
*
sizeof(int));
for (i = 0; i < argc - 1; i++)
a[i] = atoi(argv[i + 1]);
shell sort(a, argc);
for (i = 0; i < argc - 1; i++)
printf("%d ", a[i]);
printf("n");
free(a);
return 0;
488
A.2.6 Beispiel einer Fehlersuche
In der Praxis werden horizontales und vertikales Einengen frei gemischt.
Hypothese 0: Der Testfall sample 11 13 funktioniert.
Erwartet: Ausgabe
11 13.
Beobachtet: Ausgabe
0 11.
Ergebnis: Verworfen.
Hypothese 1 (horizontales Einengen): Das
Ubernehmen der Werte von der Kommandozei-
le in das Feld a funktioniert.
Erwartet: Beim Aufruf von shell sort enth alt das Feld a[] die Werte 11 und 13.
Beobachtet: wie erwartet
Ergebnis: Best atigt.
Hypothese 2 (horizontales Einengen): Nach dem Aufruf von shell sort stimmen die
Werte in a[] immer noch (
.
Variable Wert
in r
in r
argc 4 5
argv[0] "./sample" "./sample"
argv[1] "9" "11"
argv[2] "8" "13"
argv[3] "7" 0x0 (NIL)
i
1073834752 1073834752
j 1074077312 1074077312
h 1961 1961
size 4 3
Variable Wert
in r
in r
i 3 2
a[0] 9 11
a[1] 8 13
a[2] 7 0
a[3] 1961 1961
a
[0] 9 11
a
[1] 8 13
a
[2] 7 0
a
. . .
. . . und setzen den Lauf fort, um zu sehen, ob der Fehler nun auftritt
Ergebnis:
Cause-effect chain for ./sample
Arguments are 11 13 (instead of 9 8 7)
therefore at main, argc = 3 (instead of 4)
therefore at shell sort, a[2] = 0 (instead of 7)
therefore at sample.c:37, a[0] = 0 (instead of 7)
therefore the run fails.
Gegenstand aktueller Forschungen (Zeller 2002).
491
A.3 Statische Verfahren des Programmverstehens
Wir betrachten nun statische Verfahren, die Aussagen uber alle L aufe des Programms geben.
All diese Verfahren arbeiten auf der Code-Ebene (in der Regel Quellcode).
A.3.1 Lexikalische Analyse
Welche Sprachelemente sind imQuellcode enthalten? Werden Namenskonventionen eingehalten?
Ansatz: Das Programm wird in seine Sprachelemente (Bezeichner, Schl usselw orter) zerlegt.
Setzt gew ohnlich einfachen Scanner voraus, der die lexikalischen Regeln der Sprache beherrscht.
A.3.2 Syntaktische Analyse
Wie ist die Struktur des Quellcodes? Aus welchen Komponenten besteht das Programm?
Ansatz: Das Programm wird in seine grammatikalische Struktur zerlegt (sog. abstrakter Syntax-
baum): Ein Programm besteht aus Klassen, die aus Methoden und Attributen bestehen. . .
Setzt gew ohnlich nicht-trivialen Parser voraus, der die syntaktischen Regeln der Sprache be-
herrscht.
H aug Grundlage f ur statische Visualisierung d.h. Visualisierung der (groben) Programmstruk-
tur.
A.3.3 Semantische Analyse
Welche Bedeutung haben die Sprachelemente?
Ansatz: In der semantischen Analyse werden Benutzungsstellen von Programmelementen an die
jeweilige Denition gebunden.
Ben otigt Kenntnis von Sichtbarkeitsregeln.
Erm oglicht Typpr ufung und Aufsuchen von Denitionen.
Einfache Variante (lexikalisch basiert) TAGS-Tabelle: In Emacs und anderen Editoren k onnen
Sie auf Knopfdruck zur Denition jedes Programmelements springen.
492
A.3.4 Querverweis-Analyse
Wo wird dieses Programmelement ebenfalls benutzt?
Speziallfall der semantischen Analyse
Ansatz: Erstellen einer Querverweis-Tabelle, die f ur jedes Programmelement aufz ahlt, an wel-
chen Stellen es benutzt wird.
Sehr n utzlich zum Navigieren im Code!
Problem: Indirekte Verweise (z.B. uber Zeiger) k onnen nur unvollst andig ber ucksichtigt werden.
A.3.5 Kontrolluanalyse
Welche Codest ucke k onnen nacheinander ausgef uhrt werden?
Ansatz: Der Kontrollugraph (Abschnitt 17.5.2)zeigt, welche Abschnitte des Codes nacheinan-
der ausgef uhrt werden k onnen.
Ben otigt Kenntnis der Semantik von Kontrollstrukturen.
Erm oglicht Pr ufung, welcher Code welchen anderen Code aufrufen kann.
A.3.6 Datenuanalyse
Wie ieen Informationen durch das Programm?
Ansatz: Der Datenugraph (Abschnitt 17.5.2)zeigt, wie Daten durch das Programm ieen.
Ben otigt Kenntnis der Semantik von Zuweisungen.
Erm oglicht Pr ufung, welche Daten welche anderen Daten beeinussen k onnen.
Spezielle Herausforderung: indirekte Verweise wie Feld- oder Zeigerzugriffe.
493
A.3.7 Program Slicing
Welcher Code kann diese Variable beeinussen?
Ansatz: Der Programm-Abh angigkeits-Graph fat Kontroll- und Datenugraph zusammen und
stellt dar, welche Anweisungen im Programm welche Variablen beeinussen k onnen.
Ziel: Slices berechnen alle Anweisungen, die eine Variable an einer Stelle beeinussen k onnen.
Der Slice fat Daten- und Kontrollabh angigkeiten zusammen
Beispiel: Berechnung von Summe und Produkt
int main()
int a, b, sum, mul;
sum = 0;
mul = 1;
a = read();
b = read();
while (a <= b)
sum = sum + a;
mul = mul
*
a;
a = a + 1;
write(sum);
write(mul);
int main()
int a, b, sum, mul;
mul = 1;
a = read();
b = read();
while (a <= b)
mul = mul
*
a;
a = a + 1;
write(mul);
Softwarewerkzeuge.
497
Die Abh angigkeiten zwischen den Komponenten eines Systems k onnen in Form eines Abh angig-
keitsgraphen dargestellt werden:
glob.c win.c text.c aux.h
aux.c main.c types.h vars.h
prog42
main.o aux.o lib.a
glob.o win.o text.o
Ein Makele ist eine textuelle Beschreibung des Abh angigkeitsgraphen nebst Kommandos zur
Erzeugung der einzelnen Komponenten
# Dies ist ein Makefile
# Werkzeuge und Optionen werden mittels Variablen gesetzt
CC = cc
CFLAGS = -g
AR = ar
RANLIB = ranlib
# Abhangigkeiten und Kommandos
prog42: main.o aux.o lib.a
$(CC) -o prog42 main.o aux.o lib.a
main.o: main.c types.h vars.h
$(CC) -c $(CFLAGS) main.c
aux.o: aux.c types.h vars.h
$(CC) -c $(CFLAGS) aux.c
lib.a: glob.o win.o text.o
$(AR) ru lib.a glob.o win.o text.o
$(RANLIB) lib.a
glob.o: glob.c aux.h
$(CC) -c $(CFLAGS) glob.c
win.o: win.c aux.h
$(CC) -c $(CFLAGS) win.c
text.o: text.c aux.h
498
$(CC) -c $(CFLAGS) text.c
Zum Erzeugen des Systems ruft man nun Make auf, wobei man die gew unschte Zieldatei und
ggf. alternative Variablenwerte angibt:
$ make CFLAGS=-O prog42
Beim Aufruf durchwandert Make den Abh angigkeitsgraphen per Tiefensuche. Eine Zieldatei
wird neu erzeugt, wenn sie
nicht existiert oder
eine Quelldatei, von der die Zieldatei abh angt, vor k urzerer Zeit ge andert wurde als die
Zieldatei
Nach einer
Anderung werden also nur die Teile neu ubersetzt, die von der
Anderung betroffen
sind.
Beispiel 1: Keine Zieldatei existiert
$ make prog42
cc -c main.c
cc -c aux.c
cc -c glob.c
cc -c win.c
cc -c text.c
ar ru lib.a glob.o win.o text.o
ranlib lib.a
cc -o prog42 main.o aux.o lib.a
Beispiel 2: main.c wurde ge andert
$ make prog42
cc -c main.c
cc -o prog42 main.o aux.o lib.a
Beispiel 3: aux.h wurde ge andert
$ make prog42
cc -c glob.c
cc -c win.c
cc -c text.c
ar ru lib.a glob.o win.o text.o
ranlib lib.a
cc -o prog42 main.o aux.o lib.a
In der Praxis: Automatische Bestimmung der Abh angigkeiten, Spezial-Ziele zum Installieren
(make install) und L oschen (make clean)
499
B.2 Regressionstests mit DEJAGNU
Mit einem Regressionstest stellt man sicher, da die Grundfunktionalit at eines Programms auch
nach
Anderungen erhalten bleibt.
Zur Realisierung von Regressionstests baut man eine Sammlung (=Menge von Dateien)
von Testf allen auf
Die resultierenden Programmausgaben (=Dateien) werden ebenfalls gespeichert
Zum Test einer neuen Programmversion wird diese mit den Tests atzen gef uttert
Die alten Ergebnisse werden mit den neuen verglichen
Unterschiede werden dem Programmierer zur Beachtung anempfohlen
DejaGnu ist ein Werkzeug zum Automatisieren von Regressionstests.
Eigene Kommando-Sprache zumTesten interaktiver Programme (nur textuelle Ein-/Ausgabe)
Testeingaben der Form test Eingabe) Ausgabemuster)
Entspricht die Programm-Ausgabe nicht dem Ausgabemuster (regul arer Ausdruck) oder
erfolgt keine Antwort nach einer bestimmten Zeit, schl agt der Test fehl
500
Beispiel: Test einer Shell
myshell
Eingabedatei echo.exp:
# Test the set and echo commands ...
test set a = b
test echo $a b
test set a = c
test echo $a c
# Test for undefined variable ...
test echo $xxx ERROR:.
*
Ablauf:
$ runtest --tool myshell ./testsuite
Test run by zeller on Mon Jun 20 12:19:38 1994
Native configuration is sparc-sun-sunos4.1.1
=== myshell tests ===
Running ./testsuite/myshell.test/echo.exp ...
FAIL: echo $a
FAIL: echo $a
FAIL: (timeout) echo $xxx
=== myshell summary ===
# of expected passes 2
# of unexpected failures 3
$
Sehr praktisch, wenn eine fernbedienbare, wohldenierte Schnittstelle vorliegt!
Aber: Regressionstests werden schwierig bei graphisch-interaktiven Programmen, da sie schwer
automatisierbar sind.
Hier hilft nur die Simulation von Benutzereingaben (
Testversion,
return $result
Hierbei wird
$name durch den Wert der Variablen name ersetzt und
[Befehl] durch die Ausgabe des Befehls Befehl.
expr 2 + 5 gibt 7 aus; set foo [expr 2 + 5] entspricht also set foo 7.
510
Tk ist ein spezielles Kommando-Paket zur Darstellung von Benutzerober achen. Mit Tcl/Tk
lassen sich mit geringem Aufwand komplexe Ober achen erstellen.
Beispiel Ober ache f ur power-Funktion:
# entry ist eine Texteingabe
# label ist ein Anzeigefeld
entry .base -width 6 -relief sunken -textvariable base
label .label1 -text to the power
entry .power -width 6 -relief sunken -textvariable power
label .label2 -text is
label .result -textvariable result
# pack fat Elemente zusammen
pack .base .label1 .power .label2 .result -side
left -padx 1m -pady 2m
# Tastaturbindungen
bind .base <Return> set result [power $base $power]
bind .power <Return> set result [power $base $power]
Diese Eingabe erzeugt ein Programm, mit demnach Belieben Potenzen berechnet werden k onnen.
Dar uber hinaus k onnen eigene C-Funktionen als Befehle aufgerufen werden, womit eine saubere
Trennung zwischen Ober ache (Tcl/Tk-Skript) und Funktionalit at (den C-Funktionen) gegeben
ist.
511
B.7 Scanner generieren mit LEX
Problem: Erkennen lexikalischer Einheiten (Tokens) in Eingabedateien.
Lex erh alt als Eingabe eine Liste von Paaren (Regul arer Ausdruck, Aktion) und generiert daraus
eine Funktion yylex(), die die Eingabe verarbeitet. Immer, wenn ein regul arer Ausdruck in der
Eingabe erkannt wird, wird die entsprechende Aktion durchgef uhrt.
Beispiel Rechnen mit ganzen Zahlen
%%
pi return PI;
div return DIV;
mod return MOD;
[A-Za-z][A-Za-z0-9_]
*
return IDENTIFIER;
[0-9]+ return NUMBER;
"+" return PLUS;
"-" return MINUS;
"
*
" return MULT;
" " /
*
ignore
*
/;
Hierbei bedeuten
[a-z] ein beliebiges Zeichen von
a bis
z und
R
*
/R+ null bzw. ein oder mehr Auftreten von R.
Der jeweils verarbeitete Eingabetext steht dabei in der globalen String-Variablen yytext.
Beispiel Eingabe pi + c mod 25:
Ruckgabe yylex() Wert yytext
PI "pi"
PLUS "+"
IDENTIFIER "c"
MOD "mod"
NUMBER "25"
512
Lex erlaubt auch, regul are Ausdr ucke zu denieren. Damit k onnen auch komplexe Ausdr ucke
angegeben werden.
Beispiel Rechnen mit reellen Zahlen
Wir denieren die h aug wiederkehrenden Ausdr ucke [0-9] und [0-9]+ als d und D im
Dateikopf. Damit denieren wir R als regul aren Ausdruck f ur Real-Zahlen.
/
*
digit
*
/
d [0-9]
/
*
sequence of digits
*
/
D [0-9]+
/
*
real number
*
/
R ((D.d
*
)|(D)|(.D))([eE][+-]?D)?
%%
pi return PI;
-?D return INTEGER;
-?R return REAL;
[A-Za-z][A-Za-z0-9_]
*
return IDENTIFIER;
"+" return PLUS;
"-" return MINUS;
"
*
" return MULT;
"/" return DIVIDE;
" " /
*
ignore
*
/;
Es bedeuten:
R? ein optionales Auftreten von R
(R
1
|R
2
) ein Auftreten von R
1
oder R
2
Beispiel Eingabe 3pi + 2.5x
Ruckgabe yylex() Wert yytext
INTEGER "3"
PI "pi"
PLUS "2.5"
IDENTIFIER "x"
513
B.8 Parser generieren mit YACC
Problem: Erkennen von Sprachstrukturen (Grammatiken) in Eingabedateien.
Yacc erh alt als Eingabe eine Grammatik mit Aktionen, die an die Regeln der Grammatik ge-
bunden sind. Immer, wenn die betreffende Regel erkannt ist, wird die entsprechende Aktion
durchgef uhrt.
Yacc erzeugt aus der Grammatik eine Funktion yyparse(), die eine Eingabe komplett verar-
beitet und ihren semantischen Wert zur uckgibt. Die Eingabe liegt dabei in Form von Tokens vor;
zum Lesen der Tokens wird eine Funktion yylex() vorausgesetzt (siehe Lex).
Beispiel: Erkennen eines Atoms
atom : IDENTIFIER
$$ = lookup(yytext);
| PI
$$ = 3.14159265358979323846;
| INTEGER
$$ = atof(yytext);
| REAL
$$ = atof(yytext);
;
$$ ist hierbei der semantische Wert des Konstrukts.
Mit $1 . . . $n werden die semantischen Werte der Bestandteile angesprochen.
Beispiel: Auswerten einer Summe
expr : expr PLUS term
$$ = $1 + $3;
| expr MINUS term
$$ = $1 - $3;
| term
$$ = $1;
;
514
Beispiel Auswerten eines arithmetischen Ausdrucks
%token PLUS MINUS MULT DIVIDE
%token IDENTIFIER PI INTEGER REAL
%start expr
%%
expr : expr PLUS term
$$ = $1 + $3;
| expr MINUS term
$$ = $1 - $3;
| term
$$ = $1;
;
term : term MULT atom
$$ = $1
*
$3;
| term DIVIDE atom
$$ = $1 / $3;
| atom
$$ = $1;
;
atom : IDENTIFIER
$$ = lookup(yytext);
| PI
$$ = 3.14159265358979323846;
| INTEGER
$$ = atof(yytext);
| REAL
$$ = atof(yytext);
| PLUS atom
$$ = $2;
| MINUS atom
$$ = -($2);
| ( expr )
$$ = $2;
;
Angewandt auf den Ausdruck
3.0 + 2.0
*
pi / pi
liefert yyparse() den Wert 5.0.
515
B.9 Benutzer freundlich gr uen mit HELLO
Problem: Viele Benutzer beklagen sich uber die Unpers onlichkeit ihres Rechners.
Abhilfe: Das GNU Hello-Programm.
Hello bietet dem Benutzer eine wohlvertraute Begr uung. Die derzeitige Fassung spricht beson-
ders englischsprachige C-Programmierer an; eine internationalisierte Fassung ist in Arbeit.
Hello wird mit hello aufgerufen. Auf dem Bildschirm erscheint
Hello, world!
Zahlreiche Optionen sind verf ugbar:
hello --traditional gibt die