11 Software-Engineering
Nicht mit Erfindungen, sondern mit Verbesserungen
macht man Vermögen.
– Henry Ford
Unter dem Oberbegriff Software-Engineering (auf Deutsch manchmal auch Softwaretechnik genannt) werden sämtliche Arbeitsschritte der professionellen Softwareentwicklung zusammengefasst. Die in den beiden vorigen Kapiteln behandelte Programmierung ist dabei nur eine Teilaufgabe (wenn auch die wichtigste).
Die Bezeichnung Engineering legt nahe, dass hier die in über hundert Jahren gesammelte Erfahrung der Ingenieurswissenschaften auf die Erstellung von Software angewendet werden soll. In gewisser Weise arbeitet ein Softwareentwickler tatsächlich wie ein Produktingenieur: Anders als der Hacker oder Geek, für den der Rechner und die Programme Selbstzweck sind, muss er Anwendungen schreiben, die Gegenstände und Sachverhalte aus der realen Welt abbilden und verarbeiten; diese werden in der Regel von Benutzern eingesetzt, die keine IT-Profis sind.
Der heutige Stand des Software-Engineerings ist eine langfristige Konsequenz aus Überlegungen zur Überwindung der sogenannten Softwarekrise: Mitte der 60er-Jahre des vorigen Jahrhunderts überstiegen die Entwicklungskosten für Software immer häufiger die Anschaffungskosten der Hardware (obwohl Letztere gigantisch waren). Als Grund wurde vor allem erkannt, dass die Methoden der Programmierung nicht mit der exponentiellen Weiterentwicklung der Hardware Schritt halten konnten. Auf den Punkt gebracht wurde dies 1972 von Edsger Dijkstra:
»As long as there were no machines, programming was no problem at all; when we had a few weak computers, programming became a mild problem, and now that we have gigantic computers, programming has become an equally gigantic problem.«[Anm.: Übersetzung: »Als es noch keine Maschinen gab, war Programmierung überhaupt kein Problem; als wir ein paar schwache Computer hatten, wurde die Programmierung zu einem kleinen Problem, und nun, da wir gigantische Computer haben, ist die Programmierung zu einem ebenso gigantischen Problem geworden.«]
Als Ausweg aus diesen eher pessimistischen Überlegungen wurden vor allem die seit den 70er-Jahren entwickelten Verfahren der Objektorientierung gesehen. Letztlich entstammen die meisten modernen Entwicklungsmodelle dem Denkansatz der Objektorientierung, die hier nicht nur auf die reine Programmierung, sondern auf den gesamten Entwicklungsprozess angewendet wird: Ein beliebtes Softwareentwicklungsverfahren besteht etwa aus objektorientierter Analyse (OOA), objektorientiertem Design (OOD) und schließlich objektorientierter Programmierung (OOP). Viele Entwickler, die das moderne Software-Engineering geprägt haben, stammen aus dem Umfeld der ersten objektorientierten Sprache Smalltalk.
Gerade für praxistaugliche Anwendungssoftware liegt der objektorientierte Ansatz nahe, weil sich Elemente der realen Welt auf diese Weise besonders »naturgetreu« in Computerprogrammen darstellen lassen (Näheres dazu in den Java- und Ruby-Abschnitten von Kapitel 9, »Grundlagen der Programmierung«).
In diesem Kapitel werden die Grundzüge des Software-Engineerings erläutert. Es besteht aus zwei Teilen:
- Abschnitt 11.1, »Überblick«, stellt die verschiedenen Phasen des Entwicklungsprozesses vor. Außerdem erhalten Sie einen kurzen Überblick über zwei beliebte – und ziemlich unterschiedliche – Modelle der Softwareentwicklung: den Unified Process und Extreme Programming (XP).
- In Abschnitt 11.2, »Werkzeuge«, werden wichtige Helfer für das Software-Engineering beschrieben: die Diagrammspezifikation UML (Unified Modeling Language), der Einsatz von Entwurfsmustern und die Testautomatisierung durch Unit-Tests.
Wenn Sie die Ausbildung zum Fachinformatiker absolvieren – in welcher der beiden Fachrichtungen spielt keine Rolle –, sind die Informationen in diesem Kapitel auch von praktischem Interesse für Sie: Ihre Abschlussprojektarbeit ist so umfangreich, dass Sie sich keinesfalls mit der (in der Praxis leider verbreiteten) Methode »Erst Code runterhacken, dann Konzept und Dokumentation daraus entwickeln« abplagen sollten! Abgesehen davon müssen Sie bereits vor Projektbeginn eine Vorstufe des Konzepts bei der IHK einreichen und genehmigen lassen – insofern ist zumindest der Beginn der hier vorgestellten Reihenfolge ohnehin bindend für Sie.
11.1 Überblick
Im Folgenden wird zunächst der Gesamtablauf des Entwicklungsprozesses beschrieben, anschließend werden die einzelnen Phasen näher beleuchtet. Soweit möglich, geschieht dies ohne Beschränkung auf ein bestimmtes Entwicklungsmodell. Hier geht es eher darum, die allgemeinen Anforderungen des Entwicklungsprozesses darzustellen; konkrete Lösungen durch bestimmte Modelle lernen Sie im weiteren Verlauf des Kapitels kennen.
11.1.1 Der Entwicklungszyklus
Bis zu einem gewissen Grad funktioniert die Entwicklung von Software immer gleich. Es spielt keine Rolle, ob einer oder hundert Programmierer daran arbeiten und ob es sich um ein Zehn-Zeilen-Skript oder ein umfassendes Anwendungspaket handelt: Immer besteht der Prozess mindestens aus den Schritten Entwurf – Implementierung – Test. Sie bestimmen also zuerst die Aufgaben des Programms und wie sie erfüllt werden sollen, fassen sie in Anweisungen und Ausdrücke der Sprache Ihrer Wahl und überprüfen zum Schluss, ob das Programm wie erwartet funktioniert.
In größeren Projekten, an denen mehrere Entwickler arbeiten, lassen sich die folgenden Projektphasen unterscheiden:
- Planung: Klärung der Projektvorgaben und Zusammenfassung in einem Lasten- oder Pflichtenheft. An dieser Stelle beginnt auch die Arbeit des Projektmanagements, die über den gesamten Projektverlauf weitergeführt werden muss.
- Analyse: Genaue Untersuchung des Projektgegenstands. Die Geschäftsprozesse, Elemente und Daten, für die die geplante Software zuständig sein soll, müssen möglichst genau definiert und verstanden werden.
- Entwurf: Entwicklung eines Modells für die gewünschte Implementierung. Dies ist die unmittelbare Arbeitsvorlage für die Programmierer, weil auf diese Weise auch einheitliche Schnittstellen und andere gemeinsame Konventionen definiert werden.
- Implementierung: Der eigentliche Programmcode wird geschrieben.
- Test: Überprüfung auf technische Korrektheit, auf Erfüllung der Vorgaben sowie auf Benutzbarkeit durch die Zielgruppe. Je nachdem, welches Ziel wie stark verfehlt wurde, erfolgt der Rücksprung in eine frühere Entwicklungsphase.
- Dokumentation: Informationen oder Handbücher für Entwickler (zur Weiterentwicklung der Software), Administratoren (für die Installation, Konfiguration und Anpassung) sowie Endanwender (Erläuterung der Programmfunktionen) werden erstellt.
Es gibt zwei grundlegende Möglichkeiten, diese Phasen zu durchlaufen: linear oder iterativ. Bei der linearen Entwicklungsreihenfolge – beispielsweise dem klassischen Wasserfallmodell – ist die Idealvorstellung, jeden der Schritte nacheinander in sich abzuschließen, um am Ende ein fertiges Produkt zu besitzen. Bei den moderneren iterativen Entwicklungsverfahren werden diese Phasen dagegen mehrfach durchlaufen. Jeder Durchlauf erweitert und vervollständigt das Produkt – man spricht auch von einem Spiralmodell. Die sogenannten agilen Entwicklungsverfahren wie etwa Extreme Programming versuchen, die einzelnen Durchläufe so kurz wie möglich zu halten. Auf diese Weise wird häufig ein »fertiges« Produkt veröffentlicht, und Änderungswünsche lassen sich beinahe jederzeit berücksichtigen.
Beachten Sie, dass sich Projekte in der Praxis oft nicht an die klare zeitliche Abfolge der genannten Phasen halten können. Einige Aufgaben werden von unterschiedlichen Teammitgliedern ausgeführt, andere sollten den gesamten Entwicklungsprozess umfassen und begleiten. Beispielsweise ist es weltfremd und gefährlich, erst nach Fertigstellung eines ganzen Programmpakets oder -bestandteils mit dem Testen zu beginnen: Wenn Sie erst in dieser späten Phase merken, dass ein elementares Projektziel verfehlt wurde, gefährden (oder zerstören) Sie das gesamte Projekt. Den extremsten Schluss aus diesem Problem zieht das Test-driven Development (testgetriebene Entwicklung): Hier wird zuerst ein Test geschrieben und erst danach der Programmcode, der diesen Test erfüllt.
11.1.2 Planung und Analyse
In der Planungsphase stellt der Entwickler oder Projektverantwortliche sich – bei Auftragsarbeiten natürlich in Zusammenarbeit mit dem (potenziellen) Kunden – zunächst die Frage, welchen Zweck die zu entwickelnde Software erfüllen soll. Diese Grundanforderung wird zu einem Katalog von Leistungen ausgearbeitet, die die künftige Software erbringen soll. Durch das Hinzufügen von Details geht die Planung fließend in die wesentlich exaktere Analyse über.
Bei kleinen Skripten erfolgen Planung und Analyse oft während des »Hackens«. Bereits ab etwa 100 Zeilen Programmcode sollten Sie den Plan aber in irgendeiner Form schriftlich fixieren. Bei überschaubaren Kleinprojekten genügt eine einfache Textdatei mit Notizen, die Sie später durch Kopieren und Einfügen als Kommentare in Ihr Programm aufnehmen können.
Sobald auch nur eine weitere Person an dem Projekt mitarbeitet, wird diese Empfehlung zur Pflicht. Die Fehleranfälligkeit durch mangelnde Absprachen ist beträchtlich und wächst exponentiell mit der Teamgröße. Der Mindeststandard für die Zusammenarbeit sind daher Absprachen über einen bestimmten Kommentarstil.
Bedenken Sie, dass die schriftliche Fixierung aller Informationen ab dem Projektbeginn unter anderem die Grundlage für eine benutzbare Dokumentation ist.
Projektmanagement
Bereits zu Beginn der Planungsphase sollte die wichtige Tätigkeit des Projektmanagements aufgenommen werden. Diese Koordinations- und Kontrollaufgabe muss während des gesamten Projektablaufs kontinuierlich durchgeführt werden, um Projektziele, Zeit und Ressourcen im Griff zu behalten und gegebenenfalls rechtzeitig gegenzusteuern, bevor es zu Problemen kommt.
Projektmanagement (PM) ist natürlich nicht auf Softwareprojekte beschränkt, sondern wirkt im Grunde überall, wo Menschen gemeinsam Aufgaben lösen. Es handelt sich um einen Sammelbegriff für alle organisatorischen Maßnahmen, die ein Projekt zum Erfolg führen sollen. Laut DIN-Norm 69901 ist Projektmanagement die »Gesamtheit von Führungsaufgaben, -organisation, -techniken und -mitteln für die Abwicklung eines Projektes«.
Die Aufgaben des Projektmanagements lassen sich in neun sogenannte Wissensfelder unterteilen; Tabelle 11.1 zeigt eine Übersicht.
Integrationsmanagement |
Umfangsmanagement |
Zeitmanagement |
Kostenmanagement |
Qualitätsmanagement |
Personalmanagement |
Kommunikationsmanagement |
Risikomanagement |
Beschaffungsmanagement |
Im Einzelnen lassen sich die Aufgaben der verschiedenen Wissensfelder etwa folgendermaßen zusammenfassen:
- Das Integrationsmanagement kümmert sich um die Koordination der verschiedenen Projektbestandteile und -beteiligten.
- Beim Umfangsmanagement (Scope Management) geht es um die Überwachung des Projektzustands in Bezug auf die Ziele und Vorgaben. Gelegentlich wird auch erst während des Projektablaufs die Notwendigkeit einer Zieländerung erkannt.
- Das Zeitmanagement achtet auf die Einhaltung des Projektzeitplans. Eine praktische Technik, um Aufgaben in eine zeitliche Beziehung zueinander zu setzen, ist beispielsweise der im Folgenden angesprochene Netzplan.
- Das Kostenmanagement muss durch ständige Kontrolle und eventuell geeignete Kostendämpfungsmaßnahmen dafür sorgen, dass sich die Projektkosten im Rahmen des Budgets halten.
- Durch Qualitätsmanagement soll sichergestellt werden, dass alle Elemente und Teilergebnisse des Projekts einem bestimmten Standard genügen. Dazu wird unter anderem die ausführliche Dokumentation aller Projektphasen benötigt.
- Das Ressourcenmanagement verteilt die vorhandenen Arbeitsmittel und Teammitglieder möglichst effizient auf die verschiedenen Projektteile und -phasen.
- Ohne ein funktionierendes Kommunikationsmanagement scheitert ein Projekt leicht. Es ist immer zu bedenken, dass Projekte über Abteilungs- und Hierarchiegrenzen hinweg bearbeitet werden. Wer bei der Kommunikation im Projektteam starre Dienstwege einhalten möchte, gefährdet das Projekt, weil es auf diese Weise gar kein »Team« gibt. Auch die Kommunikationsmittel und -standards selbst sollten bereits in der Planungsphase festgelegt werden, um spätere Missverständnisse auszuschließen.
- Das Risikomanagement umfasst einerseits eine möglichst weitsichtige Notfallplanung, andererseits muss beim konkreten Ausfall von Arbeitsmitteln oder Teammitgliedern flexibel reagiert werden.
- Das Beschaffungsmanagement muss Kapazitäten, Nachbestellungen und Lieferzeiten von Arbeitsmitteln so koordinieren, dass möglichst keine Verzögerungen durch das Warten auf Nachschub entstehen.
Ein gutes Beispiel für die Tätigkeit des Projektmanagements ist das Erstellen von Netzplänen, die der Zeitplanung und -koordination dienen. Im Netzplan kann übersichtlich dargestellt werden, in welcher Reihenfolge die einzelnen Schritte eines Projekts durchgeführt werden und welche von ihnen einander bedingen.
Als Beispiel zur Erstellung eines Netzplans soll die folgende kurze Liste dienen, die einige Tätigkeiten zur Erstellung einer kleinen statischen Firmen-Website mit Zeitangaben in Tagen auflistet. Die optionalen Angaben A und B beziehen sich auf die beiden Mitglieder eines Zweierteams mit unterschiedlichen Kernkompetenzen; bei Aufgaben, die jeder der beiden ausführen könnte, wurden sie weggelassen:
- Inhaltliche Planung (1 Tag)
- A, B: Entwurf (1 Tag)
- A: Schreiben der Textinhalte (2 Tage)
- B: Erstellen von Grafiken und Bildern (3 Tage)
- A: Erstellen des HTML-Codes (2 Tage)
- Test und Fehlerkorrekturen (1 Tag)
- Buchung von Webspace mit Domain bei einem Hoster (3 Tage) – da der Namenswunsch sich erst aus dem Konzept ergibt, frühestens nach Abschluss des Entwurfs möglich
- Veröffentlichung (1 Tag)
Abbildung 11.1 Netzplandarstellung eines kleinen Website-Projekts
Abbildung 11.1 zeigt den Netzplan für dieses Projekt. Vorgänge wurden soweit wie möglich parallelisiert, um die Projektdauer kurz zu halten. Jeder Vorgang wird auf einer »Karte«[Anm.: Es kann praktisch sein, die einzelnen Vorgänge tatsächlich auf kleine Karten zu schreiben. So können Sie sie zunächst frei verschieben, um verschiedene Optionen zu testen.] nach folgendem Schema notiert:
+------------------------+
| Vorgangsname/-nummer |
+---+----------------+---+
|FAZ| Dauer |FEZ|
+---+ des +---+
|SAZ| Vorgangs |SEZ|
+---+----------------+---+
Oben stehen der Name und praktischerweise auch eine eindeutige Nummer des jeweiligen Vorgangs. In der Mitte wird die Dauer des Vorgangs in einer für alle Karten identischen Zeiteinheit notiert – je nach Projektumfang zum Beispiel in Stunden, Tagen oder Monaten. Die vier Felder links und rechts neben der Dauer werden erst ausgefüllt, wenn die Reihenfolge feststeht. Hier werden (relativ zum Projektstart 0) die folgenden Zeitpunkte eingetragen: frühester Anfangszeitpunkt (FAZ), spätester Anfangszeitpunkt (SAZ), frühester Endzeitpunkt (FEZ) sowie spätester Endzeitpunkt (SEZ).
Vorgänge, bei denen FAZ und SAZ sowie FEZ und SEZ jeweils identisch sind, liegen auf dem sogenannten kritischen Pfad (Critical Path). Eine Verzögerung dieses Vorgangs hat unweigerlich zur Folge, dass auch das Gesamtprojekt länger dauert. In der Abbildung wurde der kritische Pfad durch dickere Pfeillinien markiert.
Die Hauptkritik am Netzplan ist, dass die tatsächliche Dauer der Abläufe nicht grafisch dargestellt wird. Für Fälle, in denen dies erforderlich ist, gibt es aber noch zahlreiche andere Darstellungsformen für zeitliche Abläufe.
Ein Beispiel ist das Gantt-Diagramm, das die einzelnen Abläufe durch Balken symbolisiert, deren Länge ihre Dauer kennzeichnen. Praktisch jede Projektmanagement-Software – ein Beispiel unter vielen ist Microsoft Project – ermöglicht die Darstellung der Aufgabenliste in Form von Gantt-Diagrammen. Abbildung 11.2 zeigt das zuvor dargestellte Beispiel in dieser Form.
Abbildung 11.2 Das Website-Projekt als einfaches Gantt-Diagramm (Quelle: kostenloser Basis-Account bei Tom’s Planner, http://www.tomsplanner.com)
Analyseverfahren
Um einen detaillierten Plan über Umfang, Voraussetzungen, Dauer und Kosten eines Projekts erstellen zu können, muss zunächst genau untersucht werden, welches Problem das Projekt lösen soll, auf welche Weise dies geschehen soll und welche Mittel dazu erforderlich sind. Solche Untersuchungen werden mit dem Oberbegriff Analyse bezeichnet. Die wichtigsten Formen der Analyse sind die folgenden:
- Die Systemanalyse untersucht ein System mithilfe eines Modells. In der Softwareentwicklung sollte dieses Modell beschreiben, wie sich das System – also das geplante Softwareprodukt – aus der Sicht der künftigen Benutzer verhält. Dies geschieht durch die Definition von Anwendungsfällen (Use Cases) oder beim Extreme Programming durch User Stories. Das Modell sollte möglichst keine Implementierungsentscheidungen vorwegnehmen.
- Die Datenanalyse dient der systematischen Auswertung umfangreicher Informationssammlungen. Diese können neu erstellt werden – zum Beispiel durch Messungen oder auch durch Kundenbefragungen – oder aber bereits vorliegen.
- Bei der Prozessanalyse wird der Ablauf von Prozessen untersucht. Dabei kann es sich um beliebige Geschäftsvorfälle, Kommunikationsabläufe, Verwaltungs- oder Verarbeitungstätigkeiten handeln. Ziel der Prozessanalyse ist es, die beobachteten Prozesse zu optimieren. In der Softwareentwicklung geht es besonders um diejenigen Vorgänge, die durch die neue Software erledigt oder vereinfacht werden sollen.
Es gibt unterschiedliche Analysemethoden für Softwareprojekte; einige sind Teil spezieller Entwicklungsmethoden, die im weiteren Verlauf des Kapitels vorgestellt werden. Hier nur kurz zwei Beispiele:
- Die strukturierte Analyse, bereits in den 60er-Jahren von Tom De Marco entwickelt, entspricht dem Denkmodell der imperativen Programmiersprachen jener Zeit. Kern dieser Methode sind die bekannten Flussdiagramme und Programmablaufpläne. Einfache Beispiele für Flussdiagramme finden Sie in Kapitel 10, »Konzepte der Programmierung«.
- Die objektorientierte Analyse (OOA) folgt dagegen dem Paradigma der Objektorientierung und ist somit Bestandteil der meisten modernen Softwareentwicklungsprozesse. Ein wichtiges, weitverbreitetes Hilfsmittel der OOA ist die in Abschnitt 11.2.1 näher vorgestellte Unified Modeling Language (UML), deren diverse Diagrammtypen übrigens alle Phasen des Entwicklungsprozesses begleiten können.
In der Analysephase werden möglichst noch keine Implementierungsdetails festgelegt. Entscheidungen über die Hard- und Softwarebasis sowie die einzusetzende Programmiersprache sollten offenbleiben, um zu Beginn der Entwurfsphase die richtige Entscheidung zu treffen. Allerdings kann es natürlich sein, dass externe Vorgaben einzuhalten sind: Möglicherweise existiert beim Kunden bereits eine bestimmte Infrastruktur, mit der Ihr Produkt zusammenarbeiten muss. Ähnliches gilt, wenn es sich bei dem Projekt um die Erweiterung oder Anpassung vorhandener Software handelt.
Lasten- und Pflichtenheft
Die Zwischenergebnisse der Projektplanungsphase werden in einem sogenannten Lastenheft (Statement of Work) festgeschrieben. Bei Auftragsarbeiten wird es vom Kunden oder in Zusammenarbeit mit ihm erstellt. Gemäß DIN 69905 beschreibt es die »Gesamtheit der Forderungen an die Lieferungen und Leistungen eines Auftragnehmers«. Das Heft ist natürlich keineswegs nur auf Softwareprojekte beschränkt. Im Wesentlichen enthält es folgende Punkte:
- Definition des Projektziels
- Anforderungen an den Einsatz des Produkts
- allgemeine Informationen zum Produkt
- Beschreibung der Funktionen des Produkts
- Bestimmung der Leistungen, die der Auftragnehmer zu erbringen hat
- Qualitätsstandards, denen das Produkt genügen soll – unter anderem hinsichtlich seiner Zuverlässigkeit, Benutzbarkeit, Effizienz und Änderbarkeit
- weitere Informationen oder Anmerkungen
Auf der Basis des Lastenhefts entwickelt der Auftragnehmer das wesentlich präzisere Pflichtenheft (Proposal). Es beschreibt die technischen Eigenschaften des zu erstellenden Produkts. Je nach Art des Projekts gibt es viele Gliederungsmöglichkeiten für das Pflichtenheft. Hier nur ein Beispiel[Anm.: Es handelt sich um die leicht abgewandelte Form eines Industriebeispiels. Eine Übersicht über verschiedene Gliederungsmöglichkeiten finden Sie auf der folgenden Website zu einer Software-Engineering-Vorlesung an der FH Augsburg: http://www2.hs-augsburg.de/informatik/vorlesungen/se1t/script/definition/pfheft.html.]:
- Projektziele
- Projektvorgaben
- Hardwarebasis
- Softwarevoraussetzungen
- einzusetzende Arbeitsmittel
- Nebenbedingungen
- Projektanforderungen
- Aufgaben und Funktionen des Produkts
- Benutzerschnittstelle
- Lieferumfang
- Kompatibilität und Portierbarkeit
- Erweiterbarkeit und Änderbarkeit
- weitere Leistungen
- geplante Testreihen
- Qualitätssicherung
- Supportvereinbarungen
- Kostenkalkulation
- Literatur
11.1.3 Entwurf
Nach Abschluss der Analyse wird der Entwurf (Design) des Systems angefertigt. Er bildet die unmittelbare Implementierungsvorlage und sollte umso konkreter und exakter sein, je größer Team und Projektumfang sind.[Anm.: Wichtige Ausnahme: Populäre Open-Source-Projekte haben besonders viele Mitarbeiter, müssen aber aufgrund der verteilten und asynchronen Teamzusammensetzung ohne Entwurf auskommen. Neue Features werden oft ad hoc eingebaut und dann durch Votings angenommen oder abgelehnt.] In der Entwurfsphase muss unter anderem eine Entscheidung über die einzusetzenden Technologien (Hardware, Betriebssystem, Programmiersprache und Softwareumgebung) getroffen werden, sofern diese nicht von vornherein durch die zuvor diskutierten Vorgaben festgelegt sind.
Extreme Programming und andere agile Entwicklungsprozesse verzichten übrigens fast vollständig auf einen expliziten Entwurf. Sie begeben sich mit den Analyseergebnissen unmittelbar an die Implementierungsarbeit; ihre Projektkoordination erfolgt vornehmlich über gut strukturierten und kommentierten Quellcode.
Der Entwurf kümmert sich im Wesentlichen um die Architektur des Produkts. Diese beschreibt den Aufbau und das Zusammenwirken der beteiligten Hard- und Softwarekomponenten. Im Wesentlichen muss die Architekturbeschreibung folgende Fragen beantworten:
- Welche Elemente gehören zum System selbst, und welche stehen außerhalb?
- Über welche Ein- und Ausgabeschnittstellen kommuniziert das System mit seiner Umgebung?
- Über welche Schnittstellen kommunizieren die verschiedenen Komponenten des Systems miteinander?
- Welche Aufgaben muss das System selbst erfüllen, und für welche greift es auf vorhandene Komponenten zurück?
- Wird das System auf einem einzelnen Rechner ausgeführt (Standalone-System), oder kooperieren verschiedene Teile über ein Netzwerk (verteiltes System)?
Gerade der letzte Punkt bedingt zahlreiche weiter gehende Architekturentscheidungen: Das Standalone-System kann relativ frei gestaltet werden; eventuelle Einschränkungen existieren ausschließlich aufgrund der Hard- und Softwarebasis des Zielsystems. Verteilte Systeme sind dagegen erheblich komplexer – gerade dann, wenn sie in heterogenen Hardware-, Betriebssystem- und Netzwerkinfrastrukturen funktionieren sollen. Diese Interoperabilität wird immer häufiger verlangt. Es gibt unterschiedliche Arten verteilter Systeme. Zum Beispiel lassen sich die beiden folgenden grundlegenden Arten von Systemen unterscheiden:
- Bei der Client-Server-Architektur erbringt die Serveranwendung eine zentrale Dienstleistung, während die Clientanwendungen darauf zugreifen und etwa Benutzeroberflächen bereitstellen. Beispiele sind zum Beispiel ein Datenbankserver, auf den mehrere Anwendungen und Benutzer zugreifen, oder ein Printserver, der einer ganzen Abteilung einen hochwertigen Drucker zur Verfügung stellt.
- Eine Peer-to-Peer-Architektur besteht aus gleichartigen Anwendungen, die miteinander kooperieren. Beispiele sind etwa die einfachen Dateifreigaben der meisten modernen Betriebssysteme oder auch Netzwerkspiele.
Bei der Softwareentwicklung in Teams ist die Schnittstellendefinition ein besonders wichtiger Faktor. Andernfalls ergeht es dem Team wie zwei Gruppen, die von den beiden Seiten eines Berges aus mit dem Graben eines Tunnels beginnen und erst viel zu spät feststellen, dass sie sich nicht in der Mitte treffen, sondern aneinander vorbeigebuddelt haben.[Anm.: Das ist keineswegs ein akademisches Konstrukt; in der Eisenbahngeschichte ist dies durchaus schon vorgekommen.]
Das Endprodukt der Entwurfsphase ist, wie bei der Analyse, ein Modell des Systems. Auch hier kann beispielsweise die UML eingesetzt werden, um es darzustellen. Allerdings ist das Entwicklungsmodell erheblich konkreter und detailreicher als das Analysemodell.
Die verschiedenen Entwicklungsverfahren stellen diverse Methoden und Darstellungsarten für den Entwurf zur Verfügung; einige Beispiele lernen Sie in Abschnitt 11.1.6, »Konkrete Entwicklungsverfahren«, im Rahmen der einzelnen Modelle kennen.
11.1.4 Implementierung und Test
Die Implementierung, das heißt die eigentliche Programmerstellung, braucht hier im Grunde nicht mehr näher betrachtet zu werden. Schließlich war sie bereits Thema der beiden vorangegangenen Kapitel. Dennoch ist es wichtig, sich für größere Projekte – besonders im Team – an einige Regeln zu halten:
- Konsistenz: Halten Sie sich durchgehend an einmal festgelegte Konventionen für Bezeichner, Schnittstellen, Reihenfolgen, Codestruktur und Kommentare. Zumindest bei Teamprojekten gehört die Definition dieser Konventionen (der Coding Style) bereits zum Entwurf.
- Modularisierung: Sorgen Sie für Überschaubarkeit – eine Klasse darf keine »eierlegende Wollmilchsau« sein, sondern sollte genau eine Aufgabe erfüllen und mit anderen Klassen zusammenarbeiten. Dies verbessert die Wiederverwendbarkeit der einzelnen Klassen, ermöglicht häufiger den Abschluss definierter Arbeitsschritte und trägt so zu einer höheren Codequalität bei.
- Versionsverwaltung: Es ist ungemein wichtig, über alle Änderungen im Code Buch zu führen, damit mögliche Nebeneffekte auf andere Programmteile erkannt werden und damit die Änderungen sich in Problemfällen auch wieder rückgängig machen lassen. Die praktischste Möglichkeit ist der Einsatz einer automatischen Versionsverwaltung wie Subversion oder git. Änderungen durch unterschiedliche Teammitglieder werden automatisch verzeichnet; verschiedene Versionen lassen sich vergleichen, zusammenführen und notfalls auf einen früheren Stand zurücksetzen.
- Kommentare: Es ist zeitraubend und unbequem, Code nach mehreren Wochen oder gar Monaten zu lesen und herausfinden zu müssen, welche Aufgabe er erfüllt. Schon dies ist ein guter Grund für Kommentare. Diese sollten weder zu ausführlich (jeden trivialen Schritt erklärend) noch zu spärlich sein. Das im vorigen Kapitel erwähnte Javadoc generiert unmittelbar aus speziell formatierten Kommentaren die Dokumentation; in Kapitel 18, »Webserveranwendungen«, wird phpdox für PHP angesprochen. Für viele andere Sprachen sind ähnliche Lösungen verfügbar. Wer im Hinblick darauf noch immer nicht kommentiert und die Dokumentation mühevoll nachträglich erstellt, ist selbst schuld.
In vielen modernen Entwicklungsprozessen – insbesondere den agilen – gehen die Tests unmittelbar mit der Implementierung einher. Im Wesentlichen sind in dieser Phase zwei Arten von Tests wichtig:
- Unit-Tests (oder Klassentests) sind automatisierte, programmgesteuerte Tests, die die ordnungsgemäße Funktionalität von Klassen und ihren Bestandteilen überprüfen. Zu diesem Zweck stehen für viele Programmiersprachen »xUnit«-Frameworks zur Verfügung; das prominenteste Beispiel – JUnit für Java – wird im weiteren Verlauf des Kapitels noch vorgestellt. Das Test-first-Verfahren des Extreme Programmings oder das Test-driven Development gehen so weit, dass der Unit-Test noch vor der eigentlichen Klasse geschrieben wird; erst dann wird der Code implementiert, der diesen Test (hoffentlich) erfüllt.
- Eine weitere beliebte Testmethode sind Code-Reviews: Die Programmierer eines Teams lesen ihren Code gegenseitig und stellen so dessen Qualität sicher; gleichzeitig wird die Kompatibilität der Schnittstellen verbessert. In agilen Prozessen ist der Code-Review ein integrierter Bestandteil der Implementierung. Beim Extreme Programming wird beispielsweise grundsätzlich in wechselnden Paaren programmiert, sodass immer zwei Programmierer für jeden Codeteil verantwortlich sind.
Natürlich gibt es auch Testarten, die erst nach Abschluss des Projekts oder eines einzelnen Moduls ausgeführt werden können. Dazu gehören besonders die Lasttests, die die Stabilität und Performance der Software unter realistischer Arbeitsbelastung testen.
11.1.5 Dokumentation
Die Dokumentation wird in der Regel als der letzte Schritt eines Entwicklungsprozesses bezeichnet. Dieses Denken ist gefährlich, weil es dazu verführt, tatsächlich erst am Ende damit zu beginnen. Durch den entstehenden Zeitdruck werden manche Aspekte des Projekts dann schlampig, falsch oder gar nicht dokumentiert. Wie bereits erwähnt, gibt es heute praktische Werkzeuge, die die Dokumentation aus Kommentaren extrahieren. Da Sie aus Ihrem ersten oder spätestens zweiten längeren Programm (womöglich schmerzlich) lernen oder schon gelernt haben, dass Kommentare sich lohnen, können Sie diese auch gleich konform mit einem solchen Dokumentationsstandard anlegen. Moderne Entwicklungsumgebungen wie Eclipse erleichtern dies zusätzlich.
Beachten Sie, dass es mehrere Arten beziehungsweise Stufen der Dokumentation gibt:
- Die Entwicklerdokumentation dient zunächst der Arbeit des Projektteams selbst. Sie beschreibt Klassen, Module, Schnittstellen und Erweiterungsmöglichkeiten der Software und bildet damit die Arbeitsgrundlage für Änderungen und Erweiterungen. Dieser Teil der Dokumentation ist die Hauptaufgabe von Dokumentationsgeneratoren wie Javadoc. Letztendlich sollte auch der Kunde die Entwicklerdokumentation erhalten, da oft nur der Einblick in innere Zusammenhänge die genaue Funktionsweise von Programmen offenbart. Besonders wichtig ist diese Ebene der Dokumentation bei Open-Source-Projekten: Der Quellcode mit den entsprechenden Kommentaren ist das Hauptkommunikationsmittel zwischen den verteilt arbeitenden Mitgliedern der Gruppe.
- Eine Administratorendokumentation ist für technisches Fachpersonal vorgesehen, das die neue Software installieren und in Betrieb nehmen soll. Bei Einzelplatzanwendungen ist diese Person oft mit dem Endanwender identisch, sodass die Installations- und Konfigurationsanleitung hier besonders ausführlich und allgemein verständlich sein muss. Verteilte Systeme werden dagegen häufiger von IT-Fachleuten eingerichtet; diese benötigen zwar nicht unbedingt Grundlageninformationen, aber dafür besonders tief gehende Auskunft über mögliche Spezialfälle.
- Die Anwenderdokumentation schließlich beschreibt den Einsatz der Software, das heißt deren Aufgaben und die Verwendung der Benutzeroberfläche. Sie ist mit der Bedienungsanleitung technischer Geräte vergleichbar: Der Endanwender braucht nicht alle Informationen, besonders nicht über Details, die »unter der Haube« liegen, muss sich aber genau auf die Anwendungsbeschreibung verlassen können. Deshalb sollte die Anwenderdokumentation besonders verständlich geschrieben werden und sich sehr genau an der Arbeitsweise von Benutzern orientieren. Beachten Sie aber, dass auch die beste Dokumentation kein Ersatz für eine schlecht gestaltete, das heißt unergonomische oder umständliche Benutzeroberfläche sein kann.
11.1.6 Konkrete Entwicklungsverfahren
Damit Sie eine Vorstellung davon erhalten, wie Entwicklerteams in der Praxis arbeiten könnten, werden hier kurz zwei bekannte Softwareentwicklungsprozesse vorgestellt: der Unified Process und Extreme Programming.
Der Unified Process
Der Unified Software Development Process wurde von den Entwicklern der in Abschnitt 11.2.1 beschriebenen UML definiert und verwendet deren Mittel zur Darstellung von Anwendungsfällen, Abläufen und Entwürfen. Eine konkrete Implementierung des Verfahrens ist der Rational Unified Process (RUP), der Tools der Firma Rational Software einsetzt. Die Arbeitsweise des Unified Process wird vor allem durch drei Merkmale gekennzeichnet:
- Anwendungsfälle (Use Cases): Die Analyse stützt sich beim Unified Process vor allem auf die Bedürfnisse der künftigen Benutzer des Systems. Diese werden durch sogenannte Anwendungsfälle dargestellt. Sie setzen die Benutzer (Akteure) in Beziehung zu verschiedenen Vorgängen und Geschäftsvorfällen. Aufgrund der Anwendungsfälle werden die Aufgaben der Software modelliert. Beachten Sie, dass der Begriff Benutzer nicht unbedingt Menschen bezeichnen muss; es kann sich auch um interagierende Geräte oder Programme handeln. Falls Sie beispielsweise die Anwendungsfälle eines Webservers darstellen würden, wäre sein »Gesprächspartner« ein Browser. In Abschnitt 11.2.1 erfahren Sie, wie Anwendungsfälle durch UML-Diagramme dargestellt werden.
- Iterativer Prozess: Der Unified Process gehört zu den bereits angesprochenen iterativen oder inkrementellen Softwareprozessen; der Entwicklungszyklus wird mehrfach durchlaufen, wobei das Produkt schrittweise erweitert und verbessert wird.
- Architekturzentriert: Neben den Anwendungsfällen konzentriert sich der Unified Process vor allem auf die Beschreibung der Architektur des geplanten Systems. Zunächst werden anwendungsfallunabhängige Teile modelliert, beispielsweise die Schnittstellen zur Zielplattform. Anschließend werden auch die erarbeiteten Anwendungsfälle in eine Architektur umgesetzt. Auch für die Beschreibung der Architektur werden verschiedene UML-Diagrammtypen verwendet.
Um die Tätigkeiten der Teammitglieder zu beschreiben, verwendet der Unified Process vier Begriffe:
- Rollen (wer?): Aufgaben und Zuständigkeitsbereiche von Gruppen und ihren Mitgliedern werden durch Rollen beschrieben.
- Aktivitäten (wie?): Jede Rolle besteht aus einer Abfolge von Aktivitäten, also von Handlungen, die ein bestimmtes Teilziel erreichen sollen.
- Artefakte (was?): Die durch Aktivitäten verarbeiteten Projektteile werden als Artefakte bezeichnet; der Startpunkt eines Verarbeitungsschrittes wird Eingangsartefakt genannt, der Abschluss Endartefakt. Im Verlauf der Iterationsschritte werden manche Artefakte immer wieder weiterentwickelt.
- Vorgehen (wann?): Die zeitliche Abfolge der Aktivitäten wird durch ein Vorgehensmodell beschrieben.
Die einzelnen (durch die Iteration mehrmals durchlaufenen) Phasen des Unified Process ähneln denjenigen, die eingangs allgemein für die Softwareentwicklung erarbeitet wurden:
- Konzeptionsphase: Entspricht im Wesentlichen der Planungs- und Analysephase des allgemeinen Software-Engineerings: Die Anwendungsfälle werden gesammelt, geordnet und ausgewertet; hier fällt eine Vorentscheidung über den Projektfokus und -umfang. Auch mit dem Entwurf der Architektur wird bereits in dieser Phase begonnen.
- Entwurfsphase: In dieser zweiten Phase wird der Architekturentwurf fertiggestellt. Wichtige Kernkomponenten werden bereits implementiert, um mögliche Schwierigkeiten frühzeitig abschätzen zu können. Die Teilergebnisse werden eingehend mit dem Kunden besprochen, damit Zielkorrekturen durchgeführt werden können. Auch Tests und Dokumentation werden bereits begonnen.
- Konstruktionsphase: Alle Teile des Systems werden fertig implementiert, ausgiebig getestet und dokumentiert. Schließlich müssen die einzelnen Bestandteile zum Gesamtsystem verknüpft werden.
- Übergangsphase: Das System wird zu einem veröffentlichungsfähigen Paket zusammengestellt und beim Kunden installiert. Die Endanwender müssen in die Benutzung des Systems eingewiesen, bei komplexen Produkten sogar ausführlich geschult werden. Erst nach der Inbetriebnahme zeigt sich letztendlich, ob das System die geplanten Aufgaben in der Praxis erfüllt. Nun sind alle Anwender und Administratoren aufgefordert, noch vorhandene Fehler zu beschreiben und erst aus der Praxis ersichtliche Funktionsverbesserungen für die nächste Version zusammenzutragen.
Extreme Programming
Extreme Programming (XP) wurde vor allem von Kent Beck entwickelt, der aus dem Smalltalk-Umfeld stammt und auch zahlreiche Publikationen zu diesem Thema (und anderen Aspekten der Softwareentwicklung) verfasst hat. Die Bezeichnung Extreme Programming erklärt sich daher, dass sich dieser Softwareentwicklungsprozess insbesondere auf die eigentliche Programmierung konzentriert; Planung, Analyse und Entwurf werden kürzer gefasst. XP wird häufiger für kleinere Teams und für kleine bis mittlere Projekte eingesetzt. Dort kann es durch den erheblich geringeren Verwaltungsaufwand dieses Verfahrens zu einem entscheidenden Produktivitätsgewinn kommen. Allerdings wurden auch Großprojekte bereits erfolgreich nach diesem Verfahren durchgeführt.
XP gehört zu den sogenannten agilen oder leichtgewichtigen Entwicklungsprozessen: Es existieren nur wenige feste Vorgaben; das Projekt befindet sich permanent im Fluss und kann jederzeit Änderungen der Vorgaben und Anforderungen verkraften.
Die Beschreibung von Extreme Programming erfolgt am besten über seine wichtigsten Prinzipien:
- Kurze Release-Zyklen: XP erstellt keine großen, monolithischen Projekte, sondern definiert jeweils naheliegende, innerhalb weniger Tage oder höchstens Wochen erreichbare Iterationsziele. Dies bringt häufiger Erfolgserlebnisse und vor allem mehr Dynamik – auf jeder Stufe können Ziele geändert werden. Dafür kann Extreme Programming auf starre Kundenvorgaben verzichten.
- Häufige Integration: Mit den kurzen Zyklen geht die häufige Zusammenfügung der einzelnen Komponenten zu einem (möglichst) lauffähigen Gesamtsystem einher; das »Aneinandervorbeibuddeln« wird so nahezu ausgeschlossen.
- Einbeziehung des Kunden: Der Kunde wird nicht nur als Auftraggeber wahrgenommen, der einen einmal festgelegten Anforderungskatalog vorgelegt hat. Stattdessen wird jeder einzelne Entwicklungsschritt mit dem Kunden zusammen getestet; anschließend wird das weitere Vorgehen mit ihm abgestimmt.
- Programmierung in Paaren: Die Programmierer sitzen stets zu zweit an einer Aufgabe – einer tippt, beide überlegen. Da die Paare möglichst mit jeder Einzelaufgabe wechseln, erhöht dies die Teambindung, verbessert das Zusammenwirken der Programmteile und integriert Code-Reviews in den unmittelbaren Arbeitsablauf.
- Test-first-Verfahren: Es wird stets zuerst ein automatisierter Test (Unit-Test) geschrieben und ausgeführt. Nur wenn er scheitert, wird neuer Code hinzugefügt. Näheres erfahren Sie in Abschnitt 11.2.3, »Unit-Tests«.
- Integriertes Refactoring: Durch das Test-first-Verfahren und die häufigen Releases ergibt sich beinahe von selbst, dass der Code regelmäßig aufgeräumt und an die neuen Gegebenheiten angepasst wird. So wird »Zombie-Code« vermieden, der Programme verlangsamt sowie die Lesbarkeit und Wartbarkeit verschlechtert.
- 40-Stunden-Woche: Das Ziel soll ohne Überstunden erreicht werden, da es sich sonst negativ auf die Konzentrationsfähigkeit und Zufriedenheit des Teams auswirkt – dies verursacht auf lange Sicht Mehrkosten.
Scrum
Ein weiteres Organisationsmodell der agilen Softwareentwicklung ist Scrum. Das Wort ist kein Akronym, sondern ein englischer Begriff für »Gedränge«; es soll beschreiben, dass Scrum auf weitgehende Selbstorganisation des Teams setzt.
Scrum definiert drei verschiedene, klar voneinander getrennte Rollen:
- Der Product Owner ist eine Art klassischer Projektmanager, der die allgemeinen Projektziele vorgibt und gegenüber dem Kunden verantwortlich ist. Er hält sich jedoch aus der Selbstorganisation des Teams heraus.
- Das Team, idealerweise bestehend aus fünf bis neun Mitgliedern, setzt die Anforderungen des Projekts selbstverwaltet um. Dabei entscheidet jedes Teammitglied – in Absprache mit dem Rest des Teams – selbst über seine Aufgaben. Vor dem Beginn eines jeden Projektschritts (beim Scrum als Sprint bezeichnet) bestimmen die Teammitglieder ihre Ziele.
- Der Scrum Master überwacht die Produktivität des Teams und sorgt dabei für die Klärung von Problemen, die das Team am Erreichen der Projektziele hindern.
Ein Sprint oder Projektzyklus dauert im Allgemeinen zwei bis vier Wochen. Zu Beginn des Sprints finden zwei Meetings statt. Das erste Planungstreffen wird vom Product Owner organisiert; hier definiert er zusammen mit dem Team die Anforderungen des aktuellen Sprints. Das zweite Meeting wird vom Team selbst organisiert, um die Aufgaben nach Neigungen und Kenntnissen möglichst gleichmäßig auf die Teammitglieder zu verteilen.
Die einzelnen Aufgaben werden meist in Form sogenannter User Stories (Anforderungen in Alltagssprache, ein bis zwei Sätze lang) formuliert. Die Teammitglieder schätzen, wie aufwendig die Umsetzung jeder Aufgabe sein könnte. Dabei werden nicht Manntage, sondern Story Points als Maßeinheit gewählt, wobei die Umrechnung in Manntage je nach Erfahrung des Teams und Vertrautheit mit dem Projekt flexibel ist.
Alle Aufgaben des aktuellen Sprints werden in einem Sprint Backlog gesammelt – idealerweise als einzelne Papiere auf einer Tafel, die in drei Bereiche unterteilt ist: »zu erledigen«, »in Arbeit« und »erledigt«. In einem separaten Bereich werden Probleme gesammelt, die zu Verzögerungen führen können – beispielsweise, wenn der Kunde notwendige Entscheidungen zu treffen oder Daten zu liefern hat.
Jeden Tag – idealerweise jeweils zur selben Uhrzeit – führt das Team ein Daily Scrum durch, ein kurzes Meeting von maximal 15 Minuten Dauer. Hier werden eventuelle Verzögerungen und Probleme erörtert, es findet ein Austausch statt, und es wird definiert, welche Aufgaben erledigt sind. Aus Letzterem ergibt sich ein Burndown Chart – eine grafische Darstellung, die die lineare Abwärtsbewegung der zu erledigenden Story Points mit dem Ist-Zustand vergleicht.
Nach dem Abschluss eines Sprints findet eine Retrospektive statt, bei der jedes Teammitglied kurz die Ereignisse des Sprints aus seiner Sicht schildert. Die entscheidenden Fragen, die auch schriftlich fixiert werden sollten, sind »Was war gut?« (Best Practices) und »Was könnte verbessert werden?«.
Ihr Kommentar
Wie hat Ihnen das <openbook> gefallen? Wir freuen uns immer über Ihre freundlichen und kritischen Rückmeldungen.