3 Implementation von UML

Werbung
Sächs. VWA
Fritzsche: Software-Engineering
Inhalt
1
1.1
1.2
Ziele und Arbeitsmethoden der Softwaretechnologie
Methodologie der Softwareentwicklung
Die Modellierungssprache UML
2
2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8
2.9
2.10
2.11
2.12
Objektorientierte Modellierung
Klassen-Instanzen-Abstraktion
Attribute und Operationen
Sichtbarkeit und Lebensdauer
Assoziationen und Verknüpfungen
Aggregation und Komposition
Generalisierung und Spezialisierung
Vererbung und Delegation
Polymorphie
Abstrakte und konkrete Klassen
Instanzen als Laufzeitobjekte
Statechart-Modelle
Aktivitäten-Diagramme
3
3.1
3.2
3.3
3.4
3.5
Implementation von UML-Modellen
Von UML nach Java
Ein Beispiel: Baum-Klassen
Interfaces und Mehrfachvererbung
Implementation von Assoziationen und Aggregationen
Dynamische Modelle und Event-Handling
4
4.1
4.2
4.3
Systemarchitekturen
Komponentenmodelle
Verteilungsmodelle
Objektserialisierung
5
5.1
5.2
5.3
5.4
5.5
Der Softwareentwicklungsprozess
Anwendungsfall-Analyse
Methodische Aspekte der Modellierung
Qualitätssicherung
Projektmanagement und Prozessmodellierung
Konfigurationsmanagement
6
6.1
6.2
6.3
6.4
Wiederverwendung
Komponentenbasierte Softwareentwicklung - Frameworks
Entwurfsmuster
Grafische Benutzeroberflächen
Die Model-View-Controller-Architektur
1
Sächs. VWA
Fritzsche: Software-Engineering
Literatur
H. Balzert
Lehrbuch der Objektmodellierung. Analyse und Entwurf.
Spektrum Akademischer Verlag, 1999
M. Fowler, K. Scott
UML konzentriert. Eine Einführung in die Standard-Objektmodellierungssprache.
Addison-Wesley, 2. Aufl. 2000
B. Oestereich
Objektorientierte Softwareentwicklung mit der Unified Modeling Language.
Oldenbourg, 3.Aufl., 1997
W. Pree
Komponentenbasierte Softwareentwicklung mit Frameworks.
dpunkt.verlag, 1997
I. Sommerville
Software Engineering.
Addison-Wesley, 6. Aufl. 2000
UML Resource Center:
http://www.rational.com/uml/
2
Sächs. VWA
Fritzsche: Software-Engineering
1 Ziele und Arbeitsmethoden der Softwaretechnologie
1.1
Methodologie der Softwareentwicklung
Die Softwaretechnologie (Software Engineering) ist die Lehre vom Prozess der
organisierten Softwareproduktion. Sie umfasst (die Erforschung von) Theorie,
Methoden und Werkzeuge(n) zur Herstellung von Software. Das schließt
Maßnahmen zur Qualitätssicherung, die Nachnutzung von Software sowie das
Projektmanagement und das Konfigurationsmanagement ein.
Dem Prozess der Softwareentwicklung wird im konkreten betrieblichen Umfeld
jeweils ein Lebenszyklusmodell zugrunde gelegt. Bekannte Modelle sind u.a. das
Wasserfallmodell und das Spiralmodell (letzteres ist ein evolutionäres Modell). Im
Entwicklungsprozess lassen sich Entwicklungsphasen abgrenzen:
 Analyse (Anforderungsanalyse (Pflichtenheft) – Anwendungsfallanalyse –
Problembereichsanalyse) ,
 Entwurf (Softwareentwurf – Algorithmenentwurf – Komponentenentwurf –
Modelloptimierung) ,
 Implementation (reduziert sich z.T. auf eine Generierung bei Vorliegen
formaler Spezifikationen) und
 Test (Unit-Test, Integrationstest, Systemtest; teilweise auch
entwicklungsbegleitend).
Es existiert nicht eine Entwicklungsmethodik, sondern eine Methodologie (Lehre von
den Methoden ...) der Softwareentwicklung. Wichtige Aspekte der
Softwaretechnologie sind
die Entwicklung „großer“ Systeme (Entwicklergruppen über längere Zeit)
Rollenbindung beteiligter Personen
Erweiterung und Anpassung (Entwicklung endet nicht mit 1. Systemversion)
Wiederverwendung (Entwicklung beginnt nicht erst beim eigenen System)
Software-Architekturen (abhängig von eingesetzten Entwicklungsmethoden)
CASE (rechentechnische Unterstützung ist abhängig von angewandten
Entwicklungsmethoden)
Zweckbindung führt auf Musterarchitekturen
1.2
Die Modellierungssprache UML
Die Unified Modeling Language (UML) ist eine grafische Modellierungs- und
Entwurfssprache. Sie basiert auf Entwicklungen von G. Booch, J. Rumbaugh sowie
I. Jacobson und bildet seit Anfang der 1990er Jahre einen Quasi-Standard im
Software Engineering. Mit der UML werden Modelle entwickelt, die Ausschnitte
einer zu modellierenden realen oder erdachten Welt widerspiegeln. Zur Darstellung
der Modelle unterschiedlicher Art werden Diagramme verwendet. Diagramme
visualisieren und formalisieren Ausschnitte aus bzw. Sichten auf Modelle.
Diagrammtypen:
 Use-Case-Diagramm (use case diagram)
 Klassenstruktur-Diagramm (static structure diagram)
 Sequenz-Diagramm (sequence diagram)
 Zusammenarbeits-Diagramm (collaboration diagram)
 Zustands-Diagramm (statechart diagram)
3
Sächs. VWA
Fritzsche: Software-Engineering



Aktivitäten-Diagramm (activity diagram)
Komponenten-Diagramm (component diagram)
Verteilungs-Diagramm (deployment diagram)
Modelltypen:
 Use-Case-Modell
 Klassenstrukturmodell
 Interaktionsmodell (Sequenz- u. Zusammenarbeits-Diagramm)
 Zustandsmodell (Zustands- u. Aktivitäten-Diagramm)
 Komponentenmodell
 Verteilungsmodell
Charakterisierung der grafischen Modellierungssprache: In der UML-Notation
werden 4 Arten grafischer Konstrukte verwendet: Icons, 2-dimensionale Symbole,
Pfade und Strings. Im Sinne eines Graphen bilden zweidimensionale Symbole
Knoten, die durch Pfade als Kanten verbunden sein können. Strings besitzen (mit
Ausnahme von Kommentaren) eine Syntax, sie können singulär auftreten oder
anderen Sprachelementen zugeordnet sein.
Die UML ist eine formale Sprache. Die Definition der Syntax (und evtl. der
Semantik) einer formalen Sprache erfolgt mit den Mitteln einer (formalen) Sprache.
Diese Sprache heißt Metasprache und dient zur Definition einer Objektsprache. Die
UML wird auch als Metasprache zur Modellierung von UML-Konzepten selbst
eingesetzt (Metamodellierung).
2 Objektorientierte Modellierung
2.1 Klassen-Instanzen-Abstraktion
Ein Objekt ist ein (abstrakter) Gegenstand oder ein Konzept mit klarer Abgrenzung
und präziser Bedeutung.
Beispiele: Kommissar Rex, das Fenster im Haus oben links, Herr Lutze, Mediatec
GmbH, ...
Eine Klasse beschreibt eine Menge von Objekten, die
 ähnliche Struktur und ähnliche Merkmale (Attribute) besitzen,
 ähnliches Verhalten zeigen (Operationen bzw. „Methoden“),
 in Relationen zu Objekten anderer Klassen oder der gleichen Klasse stehen.
Eine Klasse kann durch Aufzählung der Objekte oder durch die Definition der
Eigenschaften der Objekte (Klassendefinition) beschrieben werden. Zu einer Klasse
gehörige Objekte werden alternativ auch als Instanzen, Instanzobjekte oder
Exemplare der Klasse bezeichnet. Klassen werden benannt.
Beispiele: Hund, Fenster, Person, Firma, ...
Objekte bilden bei der Realisierung auf einem Rechner Implementierungseinheiten.
Objekte sind immer Instanzen einer bestimmten Klasse und besitzen eine Identität
und eine Lebensdauer. Jedes Objekt kennt die Klasse, zu der es gehört. Eine
Klassendefinition umfasst (evtl. implizit) eine Beschreibung einer Vorschrift zur
Erzeugung von Instanzen. Klassenbildung ist Abstraktion (bei einer Abstraktion
werden unwesentliche Eigenschaften weggelassen; sprich: es wird von
4
Sächs. VWA
Fritzsche: Software-Engineering
5
unwesentlichen Eigenschaften abstrahiert). Abstraktion ist ein mächtiges Mittel zur
Bewältigung von Komplexität.
2.2 Attribute und Operationen
Attribute beschreiben die betrachteten strukturellen Merkmale, die alle zu einer
Klasse gehörenden Instanzen in einer gewissen spezifischen Ausprägung besitzen.
In einer Klassendefinition sind diese Attribute benannt. Jedes einzelne Objekt der
Klasse besitzt für jedes Attribut (Merkmal) eine individuelle Ausprägung (Merke:
Objekt - Merkmal -Ausprägung), die sich allerdings bei einem Objekt im Laufe der
Zeit ändern kann. „Ausprägungen“ sind Datenwerte eines in einer Klassendefinition
vorbestimmten Datentyps. Der Wertebereich ist für jedes Attribut (eventuell
impliziert) in der Klassendefinition durch Angabe eines Typnamens festgelegt.
Jedes existierende Objekt einer Klasse besitzt für jedes Attribut zu einem
bestimmten Zeitpunkt einen Wert aus dem Wertebereich. Dieser Wert kann von den
bei anderen Objekten zum selben Zeitpunkt geltenden Werten verschieden sein.
Die Gesamtheit der Werte (d.h. der Ausprägungen) aller Attribute eines Objektes zu
einem bestimmten Zeitpunkt bildet den Zustand des Objektes.
Operationen definieren das Verhalten von Objekten. Alle Instanzobjekte einer
Klasse verhalten sich in einer gewissen Weise gleichartig. Das Verhalten eines
Objektes wird dabei von individuellen Ausprägungen der Attribute mitbestimmt. Die
Verhaltensbeschreibung wird der Klassendefinition zugeordnet, und nicht jedem
Objekt einzeln. Sie existiert damit einmal unabhängig von der Anzahl vorhandener
Instanzen, was bei der Implementation von Operationen in einer objektorientierten
Programmiersprache genauso umgesetzt wird. Als „Methode“ bezeichnet man die
Implementation einer Operation für eine Klasse. Eine Methode kann jeweils auf ein
Objekt angewendet werden.
Eine Klasse wird in der UML durch ein Rechteck mit maximal drei Feldern für den
Klassennamen, die Attribute und die Operationen dargestellt. Klassennamen sollen
fett gedruckt sein und mit Großbuchstaben beginnen, die Namen von Attributen und
Operationen beginnen mit Kleinbuchstaben. Instanzobjekte werden ebenfalls als
Rechtecke dargestellt. Sie können einen Namen besitzen oder auch unbenannt
sein. In jedem Fall wird nach dem Doppelpunkt der Klassenname angegeben.
Klassen und Instanzen können gemeinsam in einem Klassenstruktur-Diagramm
dargestellt werden. Klassenstruktur-Diagramme sind eine formale, grafische
Notation für die Modellierung von Objekten, Klassen und Relationen.
Notation einer Klasse:
klassenname
[visibility] attributname : typname [= default-wert]
…
…
[visibility] operationsname ( argumentliste) : ergebnistypname
…
…
Sächs. VWA
Fritzsche: Software-Engineering
6
Notation einer Instanz:
[instanznname] : klassenname
attributname = wert
…
…
Beispiel mit Angabe der Instanziierungsrelation:
Person
name:string
vorname:string
geschlecht:char
geburtsjahr:int
+alter:int
Max:Person
Moritz:Person
2.3 Sichtbarkeit und Lebensdauer
Benennungen ordnen Klassen, Objekten, Attributen und Operationen Namen zu.
Namen sind immer innerhalb einer gewissen Umgebung (Environment) sichtbar,
d.h. unter Verwendung der Namen können die jeweiligen Dinge angesprochen
werden. Außerhalb der Umgebung sind die entsprechenden Dinge nicht
ansprechbar, d.h. nicht referenzierbar. Es werden vier relative Sichtbarkeitsbereiche
(sog. Visibility) abgegrenzt:
+
#
~
public
private
protected
package wide (Packages werden weiter unten beschrieben)
Konstruktoren sind spezielle Operationen, die der Erzeugung von Objekten dienen.
Objekte existieren solange, solange sie referenzierbar sind oder bis sie explizit aus
der Objektwelt entfernt werden.
Operationen können auf Instanzobjekte (instance scope) oder auf Klassen (class
scope) angewendet werden. Im Falle der Anwendung auf Klassen spricht man auch
von „Klassen-Methoden“.
Sächs. VWA
Fritzsche: Software-Engineering
2.4 Assoziationen und Verknüpfungen
Eine Assoziation ist eine abstrakte, d.h. nicht näher charakterisierte Beziehung
zwischen zwei (binäre A.) oder mehr Klassen. In der grafischen Darstellung werden
die Symbole der beteiligten Klassen durch eine durchgezogene Linie verbunden.
Die Enden einer Assoziationslinie können mit demselben Klassensymbol verbunden
sein.
Assoziationen höherer Ordnung (ternäre, ...) werden durch einen Rhombus
dargestellt, der durch Linien mit den Klassensymbolen verbunden ist. Assoziationen
höherer Ordnung sollten nach Möglichkeit vermieden werden. Sie sind schwerer zu
verstehen, darzustellen und zu implementieren als binäre Assoziationen.
Assoziationen können im Klassenstrukturdiagramm ein Name oder sogar eine
Klasse zugeordnet sein. Weitere Eigenschaften können durch Constraints
ausgedrückt werden.
Eine Verknüpfung (Link) ist ein Element einer Assoziation. Sie setzt eine Anzahl von
Objekten entsprechend der Assoziation in Beziehung. Ist durch eine binäre
Assoziation eine Klasse mit sich selbst verbunden, können unterschiedliche Objekte
dieser Klasse verknüpft sein oder ein Objekt mit sich selbst. Verknüpfungen
verbinden im Klassenstrukturdiagramm Instanzobjekte.
Beispiele:
7
Sächs. VWA
Fritzsche: Software-Engineering
8
In einer Assoziation können die beteiligten Klassen Rollen spielen. An den Enden
des die Assoziation kennzeichnenden Pfades können jeweils der Rollenname der
Klasse und eine Kardinalität notiert werden.
Durch die Angabe einer Kardinalität wird die Multiplizität beschrieben. Die Angabe
erfolgt durch die Aufzählung von Bereichen, die durch Komma getrennt werden.
Eine Bereichsangabe hat die allgemeine Form
untere-grenze .. obere-grenze. Ein * kann für eine nicht negative ganze Zahl zur
Kennzeichnung einer nach oben offenen Grenze gesetzt werden.
2.5 Aggregation und Komposition
Eine Aggregation ist eine Sonderform der Assoziation mit zusätzlicher Semantik und
bedeutet eine „Teil-Ganzes“-Beziehung. Objekte, die Komponenten einer Sache
repräsentieren, sind mit einem Objekt verknüpft, das die Komponentengruppe (das
Aggregat) repräsentiert. Aggregation ist über eine beliebige Anzahl von Ebenen
hinweg möglich.
Darstellung: hohle Raute an dem Ende der Assoziation, das dem Aggregat
zugeordnet ist.
Class1
Class2
1..*
Ein Objekt der Klasse Class1 repräsentiert die Komponentengruppe, Objekte der
Klasse Class2 repräsentieren die Komponenten. Eine Komponentengruppe mit
Komponenten verschiedener Typen hat entsprechend viele Aggregationen.
Eine Aggregation ist transitiv und antisymmetrisch.
Die Komposition wird als "enge" Aggregation verstanden, die eine Verbindung der
Teile mit dem Ganzen auch hinsichtlich der Lebenslinie bedeutet. Attribute einer
Klasse können als Komposition zwischen der Klasse und den Klassen (bzw. Typen)
der Attribute verstanden werden.
Darstellung: Ausgefüllte Raute anstelle der hohlen Raute.
Beispiele:
Ein Dokument besteht aus Absätzen, die ihrerseits aus mindestens einem
Satz bestehen.
Sächs. VWA
Fritzsche: Software-Engineering
9
Dokument
Absatz
Satz
1..*
1
Polygon
1
1
Verbund
GrafikVerbund
1..*
3..*
{ordered}
Eckpunkt
Punkt
y:real
x:real
farbe:Farbe
texture:Texture
Ein Polygon hat mindestens drei Eckpunkte. Die Farbe und andere
Eigenschaften sind dem Polygon fest zugeordnet. Ein Punkt existiert auch
unabhängig vom Polygon, er kann z.B. mehreren Polygonen gleichzeitig
zugeordnet sein.
2.6 Generalisierung und Spezialisierung
Generalisierung und Spezialisierung sind Vorgänge, die eine Inklusions-Relation
zwischen (mindestens) einer allgemeineren und (mindestens) einer spezielleren
Entität etablieren. Eine speziellere Entität besitzt alle Eigenschaften der
allgemeineren Entität (Inklusion) sowie zusätzliche und/oder anders ausgeprägte
Eigenschaften (sog. „is a“-Relation).
Generalisierung und Spezialisierung werden zunächst auf Klassen angewendet.
Die Inklusionsrelation ist gerichtet. Sie ist transitiv und antisymmetrisch. Eine an der
Relation beteiligte allgemeinere Klasse wird als Superklasse (Oberklasse), eine
speziellere Klasse als Subklasse (Unterklasse) bezeichnet.
Sprechweise: Ein Hund "ist ein" (is-a) Säugetier.
Die Klasse Hund ist Subklasse zur Klasse Säugetier.
Ein Student "ist ein(e)" Person.
Die Klasse Person ist Superklasse zur Klasse Student.
Eine Subklasse hat gegenüber der zugeordneten Superklasse veränderte
Eigenschaften. Dabei kann es sich um
zusätzliche Attribute,
zusätzliche Operationen,
Modifikationen bzw. spezielle Ausprägungen von Operationen,
Modifikationen von Festlegungen für Anfangswerte von Attributen
handeln.
Sächs. VWA
Fritzsche: Software-Engineering
10
Durch Generalisierung bzw. Spezialisierung entstehen bzgl. der Inklusionsrelation
zyklenfreie, gerichtete Graphen.
In einer Klassenhierarchie kann eine Klasse nur eine Superklasse haben. In einer
Klassenheterarchie kann eine Klasse mehrere Superklassen haben. Eine Klasse mit
mehr als einer Superklasse heißt Vereinigungsklasse.
Grafische Notation:
Class3
Class4
Class5
Die Spitze des Dreiecks zeigt zur Superklasse.
Constraints
Für eine Generalisierung können Constraints angegeben werden (neben dem
Dreieck in geschweiften Klammern notiert). Vordefinierte alternativ verwendbare
Angaben sind overlapping vs. disjoint sowie complete vs. incomplete.
Sind alle Subklassen angegeben (die Anordnung ist vollständig, es werden keine
weiteren Subklassen erwartet) wird complete angegeben, andernfalls
incomplete. Der implizit angenommene Standardwert (d.h. falls die Angabe fehlt)
ist incomplete.
Kann ein Nachkomme von mehr als einer Subklasse abgeleitet werden, kann dies
durch overlapping gekennzeichnet werden. Das Gegenteil kann durch
disjoint gekennzeichnet werden.
Beispiel:
Fahrzeuge können sowohl nach der Antriebsart (motorgetrieben, windgetrieben) als
auch nach dem Medium, auf bzw. in dem sie sich bewegen (Luft, Wasser, Land),
spezialisiert werden (vgl. Abbildung Abschnitt 3.3). Ein Lastkraftwagen (LKW) ist
demnach ein Fahrzeug, das motorgetrieben ist und sich auf dem Land bewegt.
2.7 Vererbung und Delegation
Als Vererbung (inheritance) wird die Weitergabe von Eigenschaften (Attribute,
Operationen, Standardinitialwerte) einer Klasse an die Subklassen bezeichnet. Die
Beschreibungen von Eigenschaften der Instanzen der Klasse werden entlang der
Inklusionsrelation (an die Subklassen) vererbt. Tatsächlich müssen bei einer Klasse
die Eigenschaften ihrer Superklasse(n) nicht noch einmal beschrieben werden, sie
gelten implizit. Von besonderem Interesse ist, dass das auch bzgl. der
Implementation gilt.
Sächs. VWA
Fritzsche: Software-Engineering
Durch Mehrfachvererbung ist es möglich, dass eine Klasse, die mehrere
Oberklassen hat, Merkmale von allen Oberklassen erbt. Ein Merkmal aus der
gleichen Vorfahrenklasse, das in mehr als einem Pfad gefunden wird, wird nur
einmal geerbt, es handelt sich um das gleiche Merkmal. Konflikte zwischen
parallelen Definitionen führen zu Mehrdeutigkeiten, die bei der
programmtechnischen Realisierung gelöst werden müssen.
Delegation ist ein Implementierungsmechanismus, mit dessen Hilfe ein Objekt eine
Operation auffängt und an ein anderes Objekt zur Ausführung sendet.
Zum Beispiel hat eine Klasse A ein Attribut, dessen Wertebereich die Instanzen
einer Klasse B umfasst. Ein Instanzobjekt der Klasse A verwaltet (eine Referenz
auf) ein Objekt der Klasse B. Eine auf ein Objekt von A angewendete Methode
kann damit ihrerseits eine entsprechende Methode auf das verwaltete Objekt von B
anwenden. Operationen werden aber nicht automatisch über die Aggregation
hinweg vererbt!
Mittels Aggregation und Delegation kann fehlende Mehrfachvererbung umgangen
werden. Es bestehen folgende Möglichkeiten:
 Delegation durch Verwendung von Rollenaggregation
 Vererbung der wichtigsten Klasse und Delegation des Restes
 Verschachtelte Generalisierung
2.8 Polymorphie
Polymorphie bedeutet Vielgestaltigkeit. Der Begriff wird hier verwendet, um hervorzuheben, dass mit demselben Namen zu unterschiedlichen Zeitpunkten unterschiedliche Methoden (d.h. unterschiedliche Implementationen von Operationen)
benannt werden können.
Beispiel:
Wir betrachten Unruhen (mobiles) und möchten mit einer Operation balancedp()
bestimmen, ob sich eine Unruhe im Gleichgewicht befindet. Abstrahiert man von
den physikalischen Gegebenheiten, handelt es sich bei den Unruhen um eine
spezielle Art gewichtsbalancierter Bäume (im Unterschied zu höhenbalancierten
Bäumen). Wir modellieren eine Klasse BinWTree mit den Attributen "linker
Nachfolger" (lsucc) und "rechter Nachfolger" (rsucc). Die Attribute sind vom Typ
BinWTree, d.h. entsprechende Attribute können Referenzen auf Objekte vom Typ
BinWTree aufnehmen. Die Armlängen (links bzw. rechts von der Aufhängung)
spielen zunächst keine Rolle. Es wird angenommen, sie sind für jede Unruhe links
und rechts gleich groß.
Jede Unruhe verwaltet ein Objekt vom Typ BinWNode. Das Attribut key der Klasse
BinWNode ist vom Typ int (ganze Zahl) und dient zur Identifikation einer Unruhe.
Nur für Unruhen ohne Nachfolger (d.h. für Blattkelemente im Baum der Unruhen)
enthält das Attribut key das Gewicht. Bei Unruhen mit Nachfolgern (inneren Knoten)
wird key der Wert 0 zugewiesen. Wird die Operation weight auf ein Objekt vom
Typ BinWTree angewendet, liefert sie bei Blattelementen den Wert von key und
sonst die Summe der Gewichte der Nachfolgerknoten.
Die Klasse BinWTreeA spezialisiert die Klasse BinWTree in der Weise, dass die
Arme einer Unruhe unterschiedlich lang sein können. Zur Speicherung der
11
Sächs. VWA
Fritzsche: Software-Engineering
12
Armlängen dienen die Attribute larm und rarm. Die Attribute lsucc und rsucc
werden von BinWTree an BinWTreeA vererbt. Die Methode balancedp() kann
sowohl auf Instanzen von BinWTree als auch von BinWTreeA angewendet
werden. Für jeden dieser Fälle wird in Abhängigkeit vom Typ des aktuellen Objekts
allerdings eine andere Methode ausgeführt. Da in diesem Fall zur Laufzeit
entschieden wird, welche Methode tatsächlich ausgeführt wird, heißt diese Art der
Polymorphie "dynamische Polymorphie". Bezogen auf die Implementation spricht
man von „später Bindung“ oder auch „dynamischer Bindung“.
BinWTree
BinWNode
-node:BinWNode
-lsucc:BinWTree
-rsucc:BinWTree
-key:int
1 +selKey:int
+selWeight:int
+setKey:void
+setWeight:void
+weight:int
+balancedp:boolean
+insLeft:void
+insRight:void
+insKeyWeight:void
0..1
0..1
BinWTreeA
-larm:int
-rarm:int
+balancedp:boolean
+insRarm:void
+insLarm:void
2.9 Abstrakte und konkrete Klassen
Eine abstrakte Klasse ist eine Klasse, die selbst keine direkten Instanzen besitzt,
deren Nachkommen aber direkte Instanzen besitzen.
Eine konkrete Klasse ist eine Klasse, die direkte Instanzen besitzen kann
("instanziierbare Klasse").
Nur konkrete Klassen können Blattklassen im Vererbungsbaum sein!
Eine abstrakte Klasse kann sowohl abstrakte Operationen als auch nicht abstrakte
Operationen definieren.
Sächs. VWA
Fritzsche: Software-Engineering
Eine Operation kann abstrakt sein. Eine abstrakte Klasse definieret in diesem Fall
nur die Signatur einer Operation, ohne eine entsprechende Methode zu
implementieren. Eine Kennzeichnung im Klassensymbol erfolgt entweder durch den
Zusatz {abstract} oder dadurch, dass die Signatur der Operation in italics gesetzt
wird. Ein Auftreten der Signatur der Operation in einer abgeleiteten Klasse (ohne
Kennzeichnung als abstrakte Operation) zeigt an, dass die abgeleitete Klasse eine
Methode für die Operation definiert.
2.10 Instanzen als Laufzeitobjekte
Ein Objekt ist als Instanz einer Klasse ein Laufzeitobjekt. Es belegt bei der
programmtechnischen Realisierung Speicherplatz, hat eine Identität und besitzt eine
gewisse Lebensdauer. Objekte können benannt werden. Das bedeutet, dass eine
Assoziation zwischen einem Namen (einem Bezeichner) und einer Objektreferenz
aufgebaut wird. Namen sind einem Sichtbarkeitsbereich (scope) zugeordnet.
Wir unterscheiden:
 global
 Paket-lokal
 Klassen-lokal (evtl. inclusive Vererbung)
 Methoden-lokal
Im Laufe der Zeit können sich solche Assoziationen ändern, d.h. ein Name kann mit
einer Referenz auf ein anderes Objekt assoziiert werden.
Typkompatibilität bedeutet, dass einem Bezeichner, der mit einer Referenz auf ein
Objekt einer Klasse assoziiert ist, ein Objekt einer anderen Klasse
("Referenzklasse") zugeordnet werden kann. Typkompatibilität wird in UML nicht
speziell unterstützt. Welche Typen kompatibel sind, hängt bei der
programmtechnischen Realisierung von der verwendeten objektorientierten
Programmiersprache ab.
Die Erzeugung eines Objektes kann auf zweierlei Weise erfolgen:
1. statisch, mit der Initialisierung des Anwendungssystems
2. dynamisch, durch Anwendung eines Konstruktors der entsprechenden
Klasse während der Ausführung einer Methode.
Objektzustände: vordefinierte Ausprägungen für Zustände von Objekten sind
 nicht existent (Widerspruch!)
13
Sächs. VWA
Fritzsche: Software-Engineering




existent: Für ein Objekt wurde Speicher erfolgreich angefordert, die
Zuordnung der Methoden aus der Klassendefinition war erfolgreich.
initialisiert
deinitialisiert
gelöscht
Für persistente Objekte werden zusätzliche Zustände erklärt: ausgelagert, imSpeicher.
Das Erzeugen und Löschen von Objekten kann in Sequenzdiagrammen dargestellt
werden. In vielen objektorientierten Programmiersprachen kann der Zeitpunkt zum
Löschen eines Objektes vom Programmierer selbst geplant werden (z.B. C++).
Objekte können miteinander mittels Nachrichten kommunizieren (senden und
empfangen). Ein Objekt kann seinen Zustand verändern infolge von Reaktionen auf
 Methodenaufrufe (invocation)
 Ereignisse
Ein Sequenzdiagramm zeigt das Verhalten von Objekten und berücksichtigt dabei
die Interaktion mit anderen Objekten durch den Austausch von Nachrichten. Mit
Hilfe von Sequenzdiagrammen werden Szenarios beschrieben.
Szenario: Folge von Ereignissen, die bei einer ganz bestimmten Ausführung eines
Systems auftritt. Es kann alle Ereignisse eines Systems betreffen oder Ereignisse,
die bestimmte Objekte eines Systems beeinflussen oder von bestimmten Objekten
erzeugt werden.
Ein Szenario erhält man durch Aufzeichnung bei der Ausführung eines Systems
oder durch gedankliche Vorausplanung der Aufzeichnung.
Im Sequenzdiagramm ist eine Aufteilung der Lebenslinie eines Objekts in parallele
Zweige möglich. Parallele Lebenslinien können an einem späteren Punkt wieder
zusammengeführt werden.
14
Sächs. VWA
Fritzsche: Software-Engineering
Object1
15
Object2
1: nachricht()
1.1: antwort()
2.11 Statechart-Modelle
Ein Zustandsautomat (das ist ein endlicher Automat) ist ein Graph, bestehend aus
Zuständen und Transitionen, der die Reaktion eines Objektes einer Klasse auf den
Empfang von "äußeren Stimuli" beschreibt. Ein Zustandsautomat ist einer Klasse
oder einer Methode zugeordnet.
Ein Zustand (state) ist die Verfassung (im Verlaufe des Lebens) eines Objektes, in
der es einer Bedingung genügt, eine Aktion ausführt oder auf ein Ereignis wartet.
Ein Objekt verweilt eine endliche Zeit in einem Zustand.
Eine Transition ist eine durch ein Ereignis verursachte Zustandsänderung eines
Objektes.
Notation:
event(argument ...) [ bedingung ]/ operation(argument ...)
Ereignisse (events) sind bemerkenswerte Vorkommnisse. In Bezug auf Statecharts
ist ein Ereignis ein Vorkommnis, das eine Transition auslöst. Es hat keine Dauer.
Der Zustand eines Objektes bestimmt die Reaktion des Objektes auf ankommende
Ereignisse. Reaktionen können Aktionen und/oder Zustandsänderungen sein.
Aktionen (actions) sind atomar und nicht unterbrechbar. Ein Zustand kann mit einer
andauernden Aktivität verbunden sein. Eine solche Aktivität wird selbst als
Zustandsautomat ausgedrückt. Eine andauernde Aktivität kann als Paar von
Aktionen ausgedrückt werden.
Notation:
Ein Statechart (Zustands-Diagramm) repräsentiert einen
Zustandsautomaten. Zustände werden durch Zustandsymbole (Rechteck mit
abgerundeten Ecken) repräsentiert. Sie können einen Namen beinhalten und
optional durch horizontale Linien in bis zu drei Bereiche geteilt werden. Spezielle
Symbole existieren für den Startzustand und Endzustände:
Sächs. VWA
Fritzsche: Software-Engineering
16
Transitionen werden durch Pfeile dargestellt, die Zustandssymbole verbinden.
Ereignisse, die Zustandsübergänge auslösen, werden als Beschriftung an die
zugehörigen Pfeile geschrieben.
Interpretation:
-
wenn sich ein Objekt in einem Zustand befindet, und ein Ereignis tritt auf, mit
dem eine seiner Transitionen beschriftet ist, geht das Objekt in den Zustand
am Ende der Transition über: Die Transition „feuert“.
wenn ein Ereignis auftritt, für das es keine vom aktuellen Zustand
ausgehende Transition gibt, wird das Ereignis ignoriert.
Übergänge ohne Ereignisbeschriftung werden automatisch ausgelöst, sobald die mit
dem Zustand verbundenen Aktionen/Aktivitäten abgeschlossen sind.
Ereignisse können mit Bedingungen verknüpft sein. Die an ein Ereignis geknüpften
Bedingungen müssen erfüllt sein, damit der erwartete Zustandswechsel erfolgen
kann.
Beispiel:
reservieren()[freiePl舩ze > 1]
Ohne Reservierung
teilweise reserviert
entry()/ruecksetzen
reservieren()
stornieren()[reserviertePl舩ze = 1]
flug_einrichten()
flug_streichen()
stornieren()[reserviertePl舩ze > 1]
stornieren()
schliessen()
reservieren()[freiePl舩ze = 1]
geschlossen
ausgebucht
schliessen()
Zustände können auch Subdiagramme enthalten. Zustände können in
- sequentielle
- parallele
Unterzustände dekomponiert werden. Eine Verfeinerung ist jeweils nur auf einem
dieser beiden Wege möglich.
Sächs. VWA
Fritzsche: Software-Engineering
17
2.12 Aktivitäten-Diagramme
Das Aktivitäten-Diagramm ist eine spezielle Art des Zustandsdiagramms, das
ausschließlich Aktivitäten und Übergänge zwischen diesen zeigt. Eine Aktivität ist
einem Zustand zugeordnet und repräsentiert eine andauernde interne Aktion.
Mehrere von einer Aktivität ausgehende Transitionen werden durch Bedingungen
unterschieden:
Activity3
[x > 0]
Activity1
Activity2
[x = 0]
[x < 0]
Activity4
Activity2
Activity3
[x = 0]
Activity4 [x < 0]
[x > 0]
Activity5
Start- und Endzustand werden wie im Zustandsdiagramm dargestellt.
Ereignisse werden nicht dargestellt. Transitionen können geteilt und synchronisiert
werden (Parallelität):
Sächs. VWA
Fritzsche: Software-Engineering
Activity1
Activity2
Activity3
Activity4
3 Implementation von UML-Modellen
3.1 Von UML nach Java
Applikationen und Applets
Eine Java-Applikation ist ein Programm in einer virtuellen Maschinensprache (Java
Virtual Machine Specification). Ein solches Programm wird interpretativ durch den
Java-Interpreter java verarbeitet. Um z.B. das Programm MyApplication
abzuarbeiten, ist in der Kommandozeile einzugeben:
java MyApplication
Der Name des auszuführenden Programmes wird dem Interpreter java als
Kommandozeilenparameter übergeben.
Durch diese Art der Verarbeitung wird Plattformunabhängigkeit gewährleistet, die
Verfügbarkeit eines Interpreters auf jeder Plattform vorausgesetzt. JavaApplikationen besitzen eine Klassenstruktur, d.h. sie bestehen aus einer Anzahl
zusammenwirkender Klassen.
Ein Java-Programm in der virtuellen Maschinensprache liegt in einer Datei vor.
Dateiextension ist .class. Eine .class-Datei wird durch den Java-Compiler aus
einer .java-Datei erzeugt, die den Programmtext enthält.
Beispiel: Die Anwendung MyApplication besteht aus einer Klasse, der
Hauptklasse MyApplication. Der Programmtext könnte wie folgt aussehen:
public class MyApplication {
public static void main (String args[]){
System.out.println("Kommandozeilenparameter:");
for (int i = args.length - 1; i>=0; i--)
System.out.println(args[i]);
18
Sächs. VWA
Fritzsche: Software-Engineering
}
}
Die Hauptklasse einer Anwendung (z.B. MyApplication) muß die Methode
main() implementieren. Mit static gekennzeichnete Methoden oder Variablen
beziehen sich auf eine Klasse als Objekt, und nicht auf ein Instanzobjekt der Klasse.
Wir nennen sie Klassenmethoden bzw. Klassenvariablen. Für jede Methode ist ein
Ergebnistyp festzulegen. Wird dieser mit void angegeben, liefert die Methode
keinen Ergebniswert.
Beim Programmaufruf können Kommandozeilen-Parameter an eine Applikation
übergeben werden. Im Beispiel kann über das String-Array args in der mainMethode auf solche Parameter zugegriffen werden.
Zur Verwaltung der Länge eines Arrays besitzt jedes Array das Feld length. Auf
dieses Feld wird wie auf eine Instanzvariable eines Objektes zugegriffen.
Strings sind immer Objekte, also keine Character-Arrays. Die Klasse String wird in
einer Klassenbibliothek bereitgestellt. Bei der Erzeugung von String-Objekten kann
eine Initialisierung mittels String-Literalen vorgenommen werden:
String s = new String("Kommandozeilenparameter:")
int, float, char, boolean bezeichnen elementare Datentypen (keine Klassen).
Zu jedem elementaren Datentyp gibt es eine korrespondierende Klasse.
Java-Programme können auf die Standard-Ein-/Ausgabe zugreifen. System ist eine
abstrakte Klasse. System.in ist eine Variable für die Standard-Eingabe. Analog ist
System.out eine Variable für die Standard-Ausgabe.
Beispiel für einen Aufruf:
java MyApplication huhu haha hoho
Kommandozeilenparameter:
hoho
haha
huhu
Applets
Applets sind Java-Anwendungen, die in HTML-Dokumente mittels eines AppletTags eingebunden werden können. Die gängigen Browser verfügen über eine JVM
zur Interpretation solcher Java-Anwendungen.
Beispiel:
<html>
<head>
<title>Applet-Demonstration</title>
<!-- (c)Hartmut Fritzsche, 20-Sept-1998-->
</head>
<body background=back_ms.gif text=#0000cc>
<h1>Lehrveranstaltung "Software Engineering"</h1>
<applet
codebase="file:/home/fritzsch/java/SE_LV"
code="ChboxDemo.class"
alt="Applet!!!"
width=500 height=300 align=bottom>
The Browser doesn't know the applet-tag.
19
Sächs. VWA
Fritzsche: Software-Engineering
</applet>
</body>
</html>
Ein Browser, der das Applet-Tag nicht kennt, überliest es. Alternative HTMLElemente können in die Applet-Umgebung eingefügt werden. Kennt ein Browser das
Applet-Tag im obigen Beispiel nicht, erscheint stattdessen "The Browser doesn't
know the applet-tag". Das Attribut ALT wird verwendet, um bei Textbrowsern
anstelle des Applets alternativen Text zu zeigen. Mit dem Attribut CODE wird die
Datei spezifiziert, in der die Hauptklasse des Applets liegt.
Jede Klasse, die ein Applet realisiert, muss von der Klasse Applet abgeleitet sein,
d.h. von dieser Klasse erben (extends …). Jedes Applet besitzt die Methoden
init(), start(), stop() und destroy(), die standardmäßig keinen Code
enthalten. Die Methoden stehen im Zusammenhang mit dem Lebenszyklus eines
Applets.
Beispiel:
import java.applet.Applet;
import java.awt.*;
public class AppletDemo extends Applet{
String text;
public void init(){
System.out.println("init");
if ((text = getParameter("text")) == null)
text = "kein text-Parameter vorhanden";
System.out.println(text);
}
public void start(){
System.out.println("start");
}
public void stop(){
System.out.println("stop");
}
public void destroy(){
System.out.println("destroy");
}
public void paint(Graphics g){
g.drawString("Hello world !",90,25);
}
}
Der Netscape-Navigator gibt Ausgaben auf der Standardausgabe über die "JavaConsole" aus.
Ist das Applet während der Präsentation geändert worden, d.h es ist ein neues
.class-File erzeugt worden, muss der Applet-Viewer neu gestartet werden, um
das geänderte Applet zu präsentieren.
20
Sächs. VWA
Fritzsche: Software-Engineering
3.2 Ein Beispiel: Baum-Klassen
Als Beispiel sollen die im Abschnitt über Polymorphie betrachteten und modellierten
Unruhen nun implementiert werden. Getreu dem Klassenmodell programmieren wir
die Klassen BinWTree, BinWTreeA und BinWNode.
public class BinWTree{
BinWNode root = new BinWNode();
BinWTree lsucc,rsucc;
void insKeyWeight(int pkey,int pweight){
root.setKey(pkey);
root.setWeight(pweight);
}
void insLeft(BinWTree tree){
lsucc = tree;
}
void insRight(BinWTree tree){
rsucc = tree;
}
int weight(){
if (root.selWeight() == 0)
return( lsucc.weight() + rsucc.weight() );
else
return( root.selWeight());
}
boolean balancedp(){
if (root.selWeight() == 0)
return(
lsucc.balancedp()
&& rsucc.balancedp()
&& (lsucc.weight() == rsucc.weight()));
else
return(true);
}
void makebalance(){
}
}
class BinWTreeA extends BinWTree{
int larm,rarm;
void insLarm(int parm){
larm = parm;
}
void insRarm(int parm){
rarm = parm;
}
boolean balancedp(){
if (root.selWeight() == 0)
return(
lsucc.balancedp()
&& rsucc.balancedp()
&& (larm * lsucc.weight()
== rarm * rsucc.weight()));
else
return(true);
}
void makebalance(){
21
Sächs. VWA
Fritzsche: Software-Engineering
int s = larm + rarm;
if (root.selWeight() == 0){
lsucc.makebalance();
rsucc.makebalance();
if (!(this.balancedp())){
rarm = lsucc.weight()*s/this.weight();
larm = s - rarm;}
System.out.println(larm);
System.out.println(rarm);
}
}
}
class BinWNode{
int key,weight;
int selWeight(){
return(weight);
}
int selKey(){
return(key);
}
void setWeight(int pweight){
weight = pweight;
}
void setKey(int pkey){
key = pkey;
}
}
Die Klasse UseBinWTree bietet eine beispielhafte Anwendung:
public class UseBinWTree {
public static void main(String args[]){
System.out.println("Hello world!");
BinWTree m1 = new BinWTree();
m1.insKeyWeight(1,0);
BinWTree m2 = new BinWTree();
m2.insKeyWeight(2,4);
BinWTree m3 = new BinWTree();
m3.insKeyWeight(3,0);
BinWTree m4 = new BinWTree();
m4.insKeyWeight(4,0);
BinWTree m5 = new BinWTree();
m5.insKeyWeight(5,1);
BinWTree m6 = new BinWTree();
m6.insKeyWeight(6,1);
BinWTree m7 = new BinWTree();
m7.insKeyWeight(7,2);
22
Sächs. VWA
Fritzsche: Software-Engineering
m4.insLeft(m5);m4.insRight(m6);
m3.insLeft(m4);m3.insRight(m7);
m1.insLeft(m2);m1.insRight(m3);
System.out.println(m1.weight());
System.out.println(m1.balancedp());
BinWTreeA ma1 = new BinWTreeA();
ma1.insKeyWeight(1,0);
BinWTreeA ma2 = new BinWTreeA();
ma2.insKeyWeight(2,3);
BinWTreeA ma3 = new BinWTreeA();
ma3.insKeyWeight(3,0);
BinWTreeA ma4 = new BinWTreeA();
ma4.insKeyWeight(4,0);
BinWTreeA ma5 = new BinWTreeA();
ma5.insKeyWeight(5,2);
BinWTreeA ma6 = new BinWTreeA();
ma6.insKeyWeight(6,1);
BinWTreeA ma7 = new BinWTreeA();
ma7.insKeyWeight(7,1);
ma4.insLeft(ma5);ma4.insRight(ma6);
ma4.insLarm(1);ma4.insRarm(2);
ma3.insLeft(ma4);ma3.insRight(ma7);
ma3.insLarm(1);ma3.insRarm(3);
ma1.insLeft(ma2);ma1.insRight(ma3);
ma1.insLarm(4);ma1.insRarm(3);
System.out.println(ma1.weight());
System.out.println(ma1.balancedp());
ma4.insLarm(4);
System.out.println(ma1.weight());
System.out.println(ma1.balancedp());
ma1.makebalance();
System.out.println(ma1.weight());
System.out.println(ma1.balancedp());
System.out.println("Bye world!");
}
}
Abarbeitung des (zuvor übersetzten) Programmes:
C:\WorkStation\SE>java UseBinWTree
Hello world!
8
true
7
23
Sächs. VWA
Fritzsche: Software-Engineering
true
7
false
2
4
1
3
4
3
7
true
Bye world!
3.3 Interfaces und Mehrfachvererbung
In Java gibt es im Unterschied zu C++ keine Mehrfachvererbung. Statt dessen gibt
es sog. Interfaces, die aber reine Schnittstellen darstellen und keinerlei
Implementierung enthalten. Interfaces definieren ausschließlich abstrakte Methoden
und Konstanten.
Eine Klasse kann ein oder mehrere Interfaces implementieren. Wenn eine Klasse
ein Interface implementiert, dann muss sie alle ihre Methoden überschreiben. Die
Eigenschaft einer Klasse, ein Interface zu implementieren, wird an ihre Nachfahren
vererbt.
3.4 Implementation von Assoziationen und Aggregationen
Zur Implementation von Assoziationen und Aggregationen mit 1:n – Beziehungen
eignen sich Vektoren und Hash-Tabellen.
24
Sächs. VWA
Fritzsche: Software-Engineering
Ein Vektor ist in Java (als Instanz der Klasse Vector) ein eindimensionales
dynamisches Array. Methoden sind addElement, insertElement,
removeElement. Die Methode size liefert die Anzahl der Elemente eines Vektors.
Hash-Tabellen bieten den statistisch gesehen schnellsten Zugriff auf Elemente einer
Elementsammlung und werden deshalb häufig eingesetzt. In ca. 70 – 90 % aller
Fälle wird ein Direktzugriff möglich sein. In Java ist eine entsprechende Klasse
Hashtable verfügbar.
3.5 Dynamische Modelle und Event-Handling
Ziel ist hier die Umsetzung von Zustandsdiagrammen in Java-Programme. Bei jeder
Mausbetätigung oder Tastatureingabe wird ein Objekt der Klasse Event bzw. einer
Subklasse dieser Klasse erzeugt. Den Programmkomponenten, die auf Events
reagieren sollen, werden zur jeweiligen Event-Art passende Listener hinzugefügt.
Die Programmierung der gewünschten Aktionen bei Eintreten bestimmter Ereignisse
erfolgt in sog. Handlern. Listener-Interfaces definieren solche Handler zur
Behandlung von Events. Ein Listener kann mehrere Event-Quellen haben. Zu einer
Event-Quelle kann es andererseits auch mehrere Listener geben.
import java.applet.*;
import java.awt.event.*;
import java.awt.*;
public class AcEvDemo2 extends Applet implements ActionListener{
public void init() {
System.out.println("Hello world!");
Button bopen = new Button("open");
Button bclose = new Button("close");
bopen.addActionListener(this);
bclose.addActionListener(this);
add(bopen);
add(bclose);
System.out.println("I am waiting for events.");
}
public void actionPerformed(ActionEvent evt){
if (evt.getActionCommand().equals("open")){
System.out.println("action in open");
}
if (evt.getActionCommand().equals("close")){
System.out.println("action in close");
}
}
}
4 Systemarchitekturen
4.1 Komponentenmodelle
Betrachtet man die logische Struktur eines objektbasierten Systems, so sieht man
Klassenstrukturen. Bei der Systemarchitektur wird dagegen häufig eine nicht
objektbasierte Komponentenstruktur zugrunde gelegt. Zur Darstellung der
25
Sächs. VWA
Fritzsche: Software-Engineering
26
Komponentenstruktur werden Komponentenmodelle verwendet.
Komponentenmodelle werden in der UML mit Komponentendiagrammen
repräsentiert. Eine Komponente stellt eine physikalische Programmeinheit dar, die
als Quellcode, Objektcode oder ausführbares Programm vorliegen kann.
Komponenten werden in Subsystemen (Paketen) organisiert.
Pakete (packages) werden zur Gruppierung von Modellelementen verwendet.
In Java umfasst ein Paket eine beliebige Anzahl von Compilationseinheiten. Pakete
können hierarchisch gegliedert sein. Dabei korrespondieren Paketnamen mit Pfad/Dateinamen.
Darstellung :
Subsystem1
Component1
Component2
4.2 Verteilungsmodelle
Das Verteilungsdiagramm ermöglicht die Modellierung expliziter physischer
Strukturen. Es enthält Knoten, auf denen Prozesse ablaufen. Knoten werden durch
Quader dargestellt.
Client1
Server1
Component1
Client2
Component2
4.3 Objektserialisierung
Die Objektserialisierung dient der persistenten Speicherung von Laufzeitobjekten
einer Java-Applikation zu einem bestimmten Zeitpunkt. Das Speichern in eine Datei
Sächs. VWA
Fritzsche: Software-Engineering
27
wird als „Serialisieren“ bezeichnet. Im Paket java.io existiert eine Klasse
ObjectOutputStream, auf die die Methode writeObject anzuwenden ist. Zu
serialisierende Objekte sind dieser Methode als Parameter zu übergeben. Das
Wiederherstellen einer Objektwelt durch Lesen aus der zuvor serialisierten
Objektwelt wird als „Deserialisieren“ bezeichnet. Dazu ist die Methode
readObject der Klasse ObjectInputStream anzuwenden.
5 Der Softwareentwicklungsprozess
5.1 Anwendungsfall-Analyse
Ein Anwendungsfall (use case) beschreibt die Interaktionen zwischen Anwendern
und dem Anwendungssystem, die notwendig sind, um einen Arbeitsgang
durchzuführen. Im Wesentlichen sind Anwendungsfälle und Akteure zu
identifizieren. Das Darstellungsmittel der UML für Anwendungsfälle sind UseCaseDiagramme. Ein UseCase-Diagramm zeigt die Beziehungen zwischen Akteuren
(actors) und Anwendungsfällen in einem System. Das System wird durch ein
Rechteck dargestellt, das die Systemgrenzen zeigt.
Im UseCase-Diagramm können auch benutzt-Beziehungen (<<uses>>) und
Generalisierungen/Spezialisierungen (<<extends>>) zwischen Anwendungsfällen
gezeigt werden.
Autovermietung
Interessent
beraten
Kunde
reservieren
Reservierungsmitarbeiter
Vertrag schlie゚en
ワbergabemitarbeiter
Fahrer
KFZ ・ergeben
KFZ zur・knehmen
Kunde
R・knahmemitarbeiter
abrechnen
5.2 Methodische Aspekte der Modellierung
In der Analysephase sind folgende Aktivitäten erforderlich:
 Zerlegung des Anwendungsbereiches in Unterbereiche
Sächs. VWA
Fritzsche: Software-Engineering
 Analyse und Spezifikation des geforderten Systemverhaltens
Während der Problembereichsanalyse werden zunächst „Geschäftsklassen“
modelliert. „Fachklassen“ beschreiben im Unterschied dazu implementierungstechnische Sachverhalte.
Zur Entwicklung eines Objektmodells wird von Rumbaugh folgendes Vorgehen
empfohlen:
1. Objektklassen identifizieren
2. ein Data Dictionary vorbereiten
3. Assoziationen zwischen Objektklassen identifizieren
4. Attribute identifizieren und zu Objektklassen hinzufügen (Operationen erst
spät beim Spezifizieren des Zustandsmodells hinzufügen)
5. Klassen mittels Vererbung organisieren
6. Zugriffspfade testen
7. das Gesamtmodell in einem iterativen Prozess verfeinern
8. Klassen zu Paketen (Teilsystemen) gruppieren
5.3 Qualitätssicherung
Die Qualitätssicherung umfasst Planung/Durchführung von
Qualitätssicherungsmaßnahmen (QSM) , die Kontrolle der Einhaltung von
Standards (ISO 9000, ... ) und die Qualitätsbewertung anhand von Metriken. Es
werden konstruktive und analytische QSM unterschieden. Zu den analytischen QSM
zählen statische Analysen, der symbolische Test und dynamische Analysen
(„Testen“). Zu den statischen Analysen zählen Kontrollfluss- und Datenflussanalyse
sowie die Programmverifikation.
5.4 Projektmanagement und Prozessmodellierung
Das Projektmanagement (PM) umfasst alle Maßnahmen zur Planung und
Verfolgung einzelner Projekte und von Projektfamilien. Zur Projektplanung zählen:
 Festlegung der Projektorganisation
 Personalplanung
 Meilenstein-/Terminplanung für alle Aktivitäten und Zuordnung zu
Bearbeitern.
Die Projektverfolgung umfasst alle technisch-organisatorischen Maßnahmen zur
Erreichung der Projektziele. Dazu zählen die Verfolgung von Meilensteinen,
Terminen und (Rest-) Aufwänden sowie die Kontrolle der Aktivitäten der Bearbeiter.
Grundlage der Projektmanagement-Aktivitäten bilden Dokumente spezieller Typen,
z.B. Aktivitätengraphen, Balkendiagramme usw. Gegenstand der Prozessmodellierung ist die Formalisierung und Computerunterstützung des Softwareentwicklungsprozesses selbst. Neben Bausteinen und Ergebnissen müssen
Aufgaben und Ressourcen verwaltet werden. Wichtig ist dabei die Konsistenzsicherung.
5.5 Konfigurationsmanagement
Das Konfigurationsmanagement umfasst Aufgaben wie
 die Kontrolle der entwickelten Quellprogramme
 die Bereitstellung von „build“-Funktionalität
 das Release-Engineering
28
Sächs. VWA
Fritzsche: Software-Engineering
Das Concurrent Versions System (CVS) ist ein System, das das Versionsmanagement auf der Ebene von Quellprogrammen unterstützt. Es ermöglicht
die Aufzeichnung der Entwicklungsgeschichte von Programmdokumenten in
Projekten und unterstützt die Gruppenarbeit (check out –check in).
6 Wiederverwendung
6.1 Komponentenbasierte Softwareentwicklung Frameworks
Klassen realisieren „Abstrakte Datentypen“. Sie verkörpern Objektfabriken, weil sie
Operationen zum Erzeugen von Exemplaren zur Verfügung stellen.
Wiederverwendung individueller Komponenten ist nicht kostenlos. Es entsteht
Aufwand für das Ausfindigmachen nachnutzbarer Komponenten. OO-Sprachen
allein garantieren keine Verbesserung der Wiederverwendbarkeit.
Ein Framework ist eine Sammlung verschiedener individueller Komponenten
mit definiertem Kooperationsverhalten zur Lösung einer Aufgabe.
Frameworks definieren in der Regel einen Großteil der Architektur. Wiederverwendbare Architekturansätze standardisieren langfristig Anwendungsgebiete.
Whitebox-Frameworks bestehen aus einer Anzahl unvollständig spezifizierter
Klassen, d.h. Klassen mit abstrakten Methoden. Diese abstrakten Methoden
heißen Einschubmethoden. Um ein Whitebox-Framework anzupassen, muß
der Programmierer die Implementation des Frameworks weitgehend kennen.
Blackbox-Frameworks gehen von einer Anzahl fertiger Komponenten aus.
Anpassungen des Frameworks werden durch Kompositionen der
Komponenten erreicht, nicht durch Vervollständigung von Klassen.
6.2 Entwurfsmuster
Ein wesentlicher Beitrag zur Thematik der Entwurfsmuster wurde von E. Gamma
geleistet. Gamma et al. Haben einen Katalog mit 23 Entwurfsmustern beschrieben.
Bekannte Entwurfsmuster sind das „Beobachter“-Muster, das „Kompositum“-Muster
und das „Strategie“-Muster. Sie finden u.a. in der Model-View-Controler-Architektur
Anwendung.
Beobachter-Muster: Definiere eine 1-zu-n-Abhängigkeit zwischen Objekten, so dass
die Änderung des Zustandes eines Objektes dazu führt, dass alle abhängigen
Objekte benachrichtigt und automatisch aktualisiert werden.
Kompositum-Muster: Füge Objekte zu Baumstrukturen zusammen, um Teil-GanzesHierarchien zu repräsentieren. Das Kompositionsmuster ermöglicht es Klienten,
einzelne Objekte sowie Kompositionen von Objekten einheitlich zu behandeln.
Strategie-Muster: Definiere eine Familie von Algorithmen, kapsele jeden einzelnen
und mache sie austauschbar. Das Strategie-Muster ermöglicht es, den Algorithmus
unabhängig von ihn nutzenden Klienten zu variieren.
29
Sächs. VWA
Fritzsche: Software-Engineering
6.3 Grafische Benutzeroberflächen
In Java existiert eine sehr gute Unterstützung für die Entwicklung von Oberflächen
durch das „Abstract Window Toolkit“ (AWT) und das Paket „Swing“. Der Aufbau der
AWT-Klassenbibliothek ist ein Beispiel für die Anwendung des Entwurfsmusters
„Kompositum“.
Layout-Manager nehmen dem Anwender die Arbeit der absoluten Positionierung
von Komponenten in Containern ab. Sie definieren Regeln, nach denen Komponenten in einem Container platziert werden. Es gibt eine Vielzahl von einfach handhabbaren bis hin zu komfortablen Layouts: BorderLayout, FlowLayout,
GridLayout, GridBagLayout, usw.
6.4 Die Model-View-Controller-Architektur
Ein Model-Objekt stellt das Anwendungsobjekt dar, das View-Objekt seine
Bildschirmrepräsentation und das Controller-Objekt bestimmt die Möglichkeiten, mit
denen auf Benutzereingaben reagiert werden kann. View und Model werden durch
den Aufbau eines Protokolls zur Benachrichtigung entkoppelt. Der
Antwortmechanismus der Oberfläche wird in einem Controller gekapselt.
30
Herunterladen