Vorlesung Informatik 2
Fachhochschule für Technik Esslingen Studiengang Wirtschaftsinformatik
Aufgaben im Projekt
Dr. rer. nat. Andreas Rau
http://www.hs-esslingen.de/~rau andreas.rau@hs-esslingen.de
In diesem Teil der Vorlesung sollen die Grundlagen der Projektarbeit und elementare Tätigkeiten beschrieben werden.
Inhalt
Folgende Rollen müssen im Projektteam wahrgenommen werden:
Projektleiter – Verantwortlich für Termine und Arbeitsteilung Legt gemeinsam mit dem Team Termine fest und überwacht diese Definiert Arbeitspakete und verteilt diese im Team
Produktmanager – Verantwortlich für Gestaltung und Nutzen Legt Gestaltung und Funktionalität aus Kundensicht fest
Testet Bedienbarkeit und intuitive Verständlichkeit von SW+Doku Systemarchitekt
Legt Programmstruktur und Modularisierung zur Arbeitsteilung fest Definiert Schnittstellen für die Integration und begleitet diese
Programmieren und dokumentieren müssen alle Teammitglieder
Rollen
Unabhängig vom gewählten Vorgehensmodell (z.B. Wasserfall oder Spirale) besteht ein Projekt stets aus folgenden Phasen die je nachdem ein- oder mehrfach durchlaufen werden.
Analyse, ca. 20%
Ziele und Anforderungen in Abstimmung mit dem Kunden festlegen.
Entwurf (Grob-/Fein-), ca. 15%
Schrittweise Ausarbeitung eines Lösungsansatzes (divide + conquer) Implementierung, ca. 40%
Realisierung des Lösungsansatzes und Erstellung von Testfällen Test, ca. 25%
Prüfung der Lösung gegen die Anforderung. Dazu muss zu jeder Anforderung ein Abnahmekriterium existieren.
Projektablauf - Phasen
Projektablauf - V-Modell
Analyse
Entwurf
Implementierung
Integrationstest
Abnahmetest
Testfälle
Abnahmekriterien
Anmerkung:
Der Begriff V-Modell wird nicht nur für diese Darstellung sondern auch für das gleichnamige Vorgehensmodell verwendet.
Zerlegung top-down Integration bottom-up
Projektdokumentation
Zu jeder Phasen gehören entsprechende Dokumente:
Analyse,
Anforderungsspez. inkl. Klassifizierung und Abnahmekriterien (Tabelle) Entwurf (Grob-/Fein-),
Entwurfsdiagramme für Systemarchitektur (Module) und GUI Entwurf Testfallbeschreibungen
Implementierung
Dokumentation des Programmcodes sowie Programmhandbuch Testfallbeschreibungen
Test
Protokolle über Fehler, deren Behebung sowie die Abnahme.
Hinweis: Plan und Realität sind meist verschieden (daher: so tun als ob!)
Anforderungsdokumentation
Die Anforderungen zu einem Projekt können im einfachsten Fall in einer Tabellenkalkulation verwaltet werden (vgl. Beispiel). Wesentliche Elemente dabei sind u.a.
Eine eindeutige Nummer für jede Anforderung
Ein Klassifizierung der Anforderung nach Art und Wichtigkeit Eine Beschreibung der Anforderung
Ein Abnahmekriterium für die Anforderung
Zustand der Anforderung (z.B. vorgeschlagen, definiert, ..., erledigt) Zuständigkeit für die Anforderung
daneben können bei Bedarf auch weitere Eigenschaften wie Abhängigkeiten, Konflikte sowie Änderungen dokumentiert werden.
Wichtig ist, das Ziel am Anfang klar zu definieren damit es nicht wandert!
Für umfangreiche Projekte mit vielen Mitarbeitern existieren spezialisierte Werkzeuge zum Anforderungsmanagement mit Hilfe einer Datenbank.
Entwurfsdokumentation
Möglichkeiten für den Architekturentwurf:
Einfaches Blockschaltbild UML
Möglichkeiten für den GUI Entwurf:
Papierskizze Malprogramm GUI Builder GUI Prototyp
Während der Architekturentwurf i.d.R. eher technischen Charakter hat, muss der GUI Entwurf frühzeitig mit dem Auftraggeber bzw. den zukünftigen Anwendern abgestimmt werden.
Programmdokumentation(1)
Zur Programmdokumentation steht in Java das Werkzeug JavaDoc zur Verfügung. Dieses extrahiert spezielle Kommentare aus dem Quelltext und generiert daraus eine HTML-Dokumentation. Auch die API-Referenz wird mit diesem Werkzeug generiert (Beispiele siehe src.zip im JDK).
Arten von JavaDoc Kommentaren: Klassen, Variablen und Methoden Position des JavaDoc Kommentars: vor dem jeweiligen Element
Aufbau eines JavaDoc Kommentars: /** Inhalt */
Der erste (Ab)Satz eines JavaDoc Kommentars dient i.d.R. als Kurzbeschreibung. Der restliche Inhalt kann bei Bedarf mit HTML formatiert werden. Daneben stehen besondere Makros der Form @name zum einfügen/kennzeichnen besonderer Informationen zur Verfügung.
Dazu gehören z.B. der Name des Autors oder Methodenparameter.
Programmdokumentation(2)
/** Klasse zur Darstellung einer Person * @autor Andreas Rau
*/public class Person {
/** Der Name der Person */
String name;
/** Liefert den Namen der Person zurück.
* @return der Name der Person.
*/
public String getName() { return name;
}
/** Setzt den Namen der Person.
* @param name der neue Name der Person.
*/
public void setName( String name) { this.name = name;
}}
Projektdokumentation
Die Projektdokumentation verfolgt im wesentlichen 2 Ziele Grundlage für Projektplanung und Steuerung
Grundlage für Nachvollziehbarkeit (Haftung!)
Parnas: "A rational design process. How and why to fake it."
Projektplanung
Arbeitspakete, Meilensteine Nachvollziehbarkeit
Anforderungen
Alternativen / Entwurfsentscheidungen Änderungshistorie / Versionsverwaltung Testprotokolle
Projektplanung(1)
`Would you tell me, please, which way I ought to go from here?'
`That depends a good deal on where you want to get to,' said the Cat.
`I don't much care where--' said Alice.
`Then it doesn't matter which way you go,' said the Cat.
Projektplanung ist eine hohe Kunst und erfordert vor allem Erfahrung.
Diese Projektplanungserfahrung erwirbt man nur durch Übung Planung ist nicht alles, aber ohne Plan ist alles nichts
● Planung ist Voraussetzung für Arbeitsteilung (Wer, Wann, Was)
● Planung ist Voraussetzung für Projektsteuerung (Soll-Ist Vergleich) Böse Zugen behaupten "Planung ist der Ersatz des Zufalls durch den Irrtum" denn: "Erstens kommt es anders, und zweitens als man denkt."
Der Projektplan ist also ein lebendiges Dokument und muss lfd. gepflegt werden. Die "Atemluft" des Projektplans ist die Kommunikation im Team.
Projektplanung(2)
Vorgehensweise bei der Planung
● Planung ist nur so gut wie der Informationsstand
● Am Anfang ist meist nur der Endetermin bekannt
● Planung von hinten nach vorne (vorwärts geht schief!)
● Im ersten Schritt Planung in Phasen / Meilensteinen
● Im zweiten Schritt Verfeinerung durch konkrete Arbeitspakete
Es ist nicht wichtig, dass die Planung 100% stimmt (das geht nicht, außer man kann hellsehen). Viel wichtiger ist, dass die Planung laufend überwacht und bei Abweichungen entsprechend reagiert wird. Die Inhalte des Plans sind typischerweise elastisch, der Endtermin (und das Budget) ist bei den meisten Projekten fest.
Ein unrealistischer Plan, wird von der Realität eingeholt!
Buchtipp: Tom deMarco, "Der Termin"
Modellierung(1)
Grafische Modellierung
● Der Mensch ist ein Augentier
● Ein Bild sagt mehr als tausend Worte
● Darstellung von Strukturen statt Details
Im Quelltext erkennt man oft den "Wald vor lauter Bäumen" nicht
● Linderung durch Einrückung
Problem: Bruch zwischen Modellierung und Implementierung; verschärft durch iterative Vorgehensmodelle (synchrone Verfeinerung nötig).
Lösung: Moderne Werkzeuge unterstützen "Round-Trip" Engineering Round-Trip Engineering:
Modellieren->Code generieren->Implementieren->Code importieren->...
Modellierung(2)
Modellieren, aber wie?
"Zuerst gab es keine Notation.
Dann gab es viele Notationen.
Jetzt gibt es UML."
UML kennt verschiedene Arten von Diagrammen zur Modellierung von Struktur und Verhalten.
Wir werden haupsächlich die Struktur modellieren.
Aber: Keine Notation ist perfekt!
Objekt : Klasse
Attribute
Operationen
+ publicInstVar : Typ - privateInstVar : Typ
~ packageInstVar : Typ
# protectedInstVar : Typ + publicClassVar : Typ - privateClassVar : Typ
~ packageClassVar : Typ
# protectedClassVar : Typ + name1(arg : Typ) : Typ + name2(arg : Typ) : Typ
Modellierung(3)
Aggregation bzw.
Komposition Vererbung
Assoziation
0..1 kein oder ein 1..1 genau ein
0..* kein oder viele 1..* einer oder viele
n
m n
physikalische Struktur logische Struktur n/m:
Modellierung(4)
Schrittweise Verfeinerung (top-down):
Zuerst Struktur (Grundriss)
● Klassen
● Beziehungen
● Kardinalitäten
Dann Inhalt (Einrichtung)
●Attribute
●Operationen
●Sichtbarkeit
Modellierung erfordert Talent und Erfahrung. Die Modellierung der Welt ist einfacher als die Modellierung der Technik, hat aber auch ihre Tücken.
Das erste Modell ist nicht das letzte!
Redesign im Modell ist leichter als Redesign im Code!
Test
Es gehört zu den Tücken des Testens, daß Tests nur die Anwesenheit von Fehlern zeigen können, nicht jedoch ihre Abwesenheit. In diesem Sinne ist ein erfolgreicher Test einer der scheitert (d.h. Fehler findet) und eben nicht erfolgreich durchläuft (wenn der oder die Fehler behoben sind sollte er das natürlich irgendwann tun).
Aus einem fehlerfreien Testlauf zu schließen, die Software sei fehlerfrei ist also ein Trugschluss: Es können sehr wohl noch Fehler vorhanden sein, man muss u.U. nur genauer hinsehen. Damit hängt die Qualität eines Testergebnisses direkt von der Qualität (=Gemeinheit) der Testfälle ab. Ein guter Tester zeichnet sich durch eine Mischung aus Kreativität und Boshaftigkeit aus, mit der es ihm immer wieder gelingt Fälle zu finden, die dem Programmierer entgangen sind. Dazu sollten Programmierer und Tester möglichst zwei verschiedene Personen sein.
Test
Voraussetzungen für erfolgreichen Test
● Fehlerhafter Programmteil muss ausgeführt werden
● Fehler muss eine beobachtbare Wirkung haben Ablauf/Bestandteile eines Testfalls
● Testvorbereitung (Initialisierung)
● Testprozedur (Durchführung)
● Testauswertung (Soll-Ist Vergleich)
● ggf. Protokollierung (bei automatischen Tests)
● ggf. Testnachbereitung (Clean-Up)
Man benötigt also für jeden Test ein Sollergebnis. Dieses kann man entweder der Spezifikation entnehmen (Ein Sollergebnis ist ein WAS, kein WIE), von Hand bzw. mit Köpfchen berechnen oder einem "Orakel"
entnehmen (dies kann z.B. die Vorgängerversion eines Programms sein).
Test
In einem klassischen Entwicklungsprozess (Wasserfall) findet der Test am Ende statt – wenn überhaupt. Oftmals bleibt zum Testen "zuwenig Zeit" mit dem Ergebnis, dass Fehler nicht oder erst sehr spät gefunden werden wodurch Aufwand und Hektik weiter steigen – ein Teufelskreis!
Gleichzeitig wissen wir, dass Fehler um so teurer zu beheben sind, je später sie gefunden werden. Der GAU ist, wenn in Analyse oder Design Fehler passieren, die erst vom Anwender oder in der nächsten Version gefunden werden.
Beispiele
● Vergessene oder fehlerhafte Funktion aufgrund eines Analysefehlers
● Nicht erweiterbare Architektur aufgrund eines Designfehlers
Aus diesem Grund scheint es naheliegend, möglichst früh und möglichst oft zu testen. Bedenkt man dabei noch, daß jede Anforderung mit einem testbaren Abnahmekriterium untermauert sein sollte kann dies soweit führen, dass man Tests vor den eigentlichen Funktionen implementiert.
Test
Testen ist jedoch aufwendig. Will man viel und oft testen kommt man daher an einer Testautomatisierung nicht vorbei. Diese bietet überdies gegenüber manuellen Tests den Vorteil, reproduzierbare Ergebnisse zu liefern. Damit lassen sie sich neben der Entdeckung von Fehlern auch als Kontrollinstrument bei deren Behebung nutzen. Wird ein Fehler manuell gefunden sollte ggf. zunächst ein Testfall implementiert werden, der diesen Fehler provoziert/findet.
Da automatische Tests keinen Bediener erfordern ist es z.B. möglich, jede Nacht alle Tests durchlaufen zu lassen. Mit solchen Regressionstests die sowohl alte als auch neue Funktionen abdecken, kann man auch schnell erkennen, ob man beim Implementieren neuer Programmteile versehentlich etwas altes "kaputtgemacht" hat (vgl.
"Fernwirkung" innerhalb von Software).
Test
Ein automatisierter Testfall besteht zunächst einmal aus
● dem Testling
● einem Testtreiber (Test Driver)
Der Testling kann ein Modul, eine Klasse oder eine Methode sein. Die Aufgabe des Testtreibers ist es, die Umgebung für den Test vorbereiten und den Testling gemäß Testablauf zu stimulieren (d.h. aufzurufen).
Benötigt der Testling weitere Funktionen können diese ggf. durch einen Teststummel (Test Stub) simuliert werden. Wenn man gemäß V-Modell bottom-up testet, d.h. mit den elementaren Funktionen beginnt, kann man diese später den höherwertigen Funktionen auch direkt bereitstellen.
In Java bringt man Testfälle sinnvollerweise im selben Paket wie den Testling unter, realisiert sie jedoch als eigene Klasse(n). Dabei kann Java über den CLASSPATH verschiedene physikalische Verzeichnisbäume zu einem gemeinsamen virtuellen Paket verbinden (Vorteil bei Auslieferung).
Test
Zur vereinfachten Implementierung von Testfällen steht in Java das JUnit Framework zur Verfügung (siehe www.junit.org) das mittlerweile auch in viele andere Programmiersprachen portiert wurde (z.B. nunit für .net). Mit seiner Hilfe lassen sich sowohl einzelne Tests als auch Gruppen von Tests einfach implementieren und durchführen. Eine JUnit Testklasse erbt von junit.framework.TestCase und hat folgende Bestandteile:
Ein oder mehrere Testfälle in Methoden, die jeweils mit test- beginnen
public void testAddition() { int a = 5;
int b = 7;
int expected = 13;
Assert.assertTrue( a+b == expected);
}
Eine suite()-Methode zur Bündelung mehrere Testfälle aus einer Klasse
public static Test suite() {
TestSuite suite = new TestSuite(SimpleTest.class);
return suite;
}
Test
Der Test grafischer Oberflächen lässt sich traditionell schwer automatisieren. In Java bestehen dazu prinzipiell 2 Möglichkeiten
● Nachbildung der Benutzeraktionen
● Nachbildung der Wirkung von Benutzeraktionen
Ersteres ist möglich unter Verwendung der Klasse java.awt.Robot. Mit Hilfe dieser Klasse kann man dem Betriebssystem(!) Benutzeraktionen wie Mausklicks oder Tastendrücke vorgaukeln. Allerdings können Layout- Änderungen dazu führen, dass der Testfall "danebenklickt".
Zweiteres ist möglich unter Verwendung der APIs der Swing Komponenten. Am offensichtlichsten ist dies bei AbstractButton.doClick().
Diese Methode ist aufwendiger zu implementieren dafür jedoch weitgehend unabhängig vom Layout.
Auf diese beiden Arten kann man auch automatische Demos realisieren.
Internationalisierung
Unter Internationalisierung versteht man die Anpassung von Software an unterschiedliche nationale Gepflogenheiten. Dies betrifft sowohl Texte als auch die Formatierung von Zahlen und Datumsangaben.
Zur Internationalisierung von Texten trennt man diese vom eigentlichen Programmcode und lagert Sie in Form von Dateien (sog.
ResourceBundles) aus. Diese können dann unabhängig vom eigentlichen Programm in verschiedene Sprachen übersetzt werden. Die Einbindung ins Programm erfolgt, indem man über die Klasse ResourceBundle das
"passende" ResourceBundle anfordert und anschließend von diesem die jeweiligen Strings abfragt.
ResourceBundle strings = ResourceBundle.getBundle( "beispiel", Locale.GERMANY);
...JLabel label = new JLabel( strings.getString( "<symbolname>"));
Mit der Klasse Properties kann man auf ähnliche Weise Benutzereinstellungen in Konfigurationsdateien auslagern.
Auslieferung
In Java werden bei der Auslieferung direkt die .class Dateien ausgeliefert und können dann überall durch die virtuelle Maschine ausgeführt werden
(java -jar name.jar) - write once, run anywhere, kein .exe!).
Zur Vereinfachung von Auslieferung und Installation besteht die Möglichkeit, die gesamte Software in einer sog. jar-Datei (jar=Java ARchive) zu verpacken. Diese jar-Datei kann direkt von der virtuellen Maschine ausgeführt werden, und stellt im Grunde nichts anderes als ein zip-Archiv mit zusätzlichen Metainformationen, z.B.
Manifest-Version: 1.0 Main-Class: classname
Letztere sind im sog. Manifest gespeichert. Dieses muss den Namen
"MANIFEST.MF" haben und sich im Verzeichnis "META-INF" innerhalb der zip-Datei befinden. Statt WinZip kann auch das J2SDK-Tool "jar" zur Erzeugung der .jar-Datei verwendet werden (jar cvfm name.jar manifest files)