Das Scheitern von Entwicklungsmodellen

From chaoswiki
Jump to navigation Jump to search

Übersetzung von Johann Franz

Es gibt höllisch viele Entwicklungsmodelle da draussen. Da ist das Domain Specific Modelling (DSM), das Model Driven Software Development (MDSD), es gibt ausserdem Design Patterns, den Rational Unified Process (RUP) und seinen schlanken Pendanten, das V-Model XT. Und es gibt Extreme Programming (XP), das einzige Modell, welches älter als ein paar Jahre ist.

Dieses Dokument versucht zu analysieren, warum Extreme Programming offenbar das einzige Entwicklungsmodell ist, das der Marktbelastung standhalten kann.

Die Realität der Softwareentwicklung

Die Realität der Softwareentwicklung ist bedrückend. Es gibt buchstäblich Tausende brilliante Köpfe in der Softwareindustrie. Diese Leute hacken für ihren Lebensunterhalt und sie lesen viele Bücher und Computerzeitschriften. In diesen Zeitschriften finden sie jede Menge interessante Konzepte, Algorithmen und andere Dinge. Ihre Köpfe sind voll von brillianten Ideen, die jedoch in keinerlei Beziehung zu den Problemen stehen, die sie zu lösen versuchen.

Eine typische Niederlage

Was also in 80% der Softwareentwicklungsfälle geschieht ist das Folgende:

  • Ein Kunde geht zur einem Unternehmen und fragt nach einer Lösung. Der Kunde ist sich nur grob bewusst, was er genau will, sodass er keine detaillierte Beschreibung geben kann. Auch kümmert es ihn nicht, da es aus seiner Sicht Aufgabe des Unternehmens ist, dies herauszufinden.
  • Ein Analytiker des Unternehmens trinkt literweise Kaffee, um sein Riesenhirn auf eine Betriebstemperatur zu bekommen. Dann denkt er sich eine Strategie aus, ein allmächtiges Produkt innerhalb des vorgegebenen Zeitrahmens zu erschaffen, und weist die dazu nötigen Mittel zu. Dabei denkt er weit in die Zukunft voraus und findet heraus, welche Algorithmen in seinem Projekt benutzt werden, die auch für künftige Projekte einen Nutzen haben sollen.
  • Ein brillanter Programmierer setzt sich hin und beginnt, den Code zu implementieren, über den er in der neusten Ausgabe einer Computerzeitschrift etwas gelesen hat. Dieser ist in keiner Weise bezogen auf das Programm, das er schreiben soll, aber es ergibt eine nette Extrafunktion.
  • Die Zeit für das Projekt geht zur Neige, während keine der gewünschten Funktionalitäten bereits fertiggestellt ist. Nun geraten die Programmierer unter Druck und machen schmutzige Hacks bis 4 Uhr früh, um das Projekt zwei Monate nach Abgabetermin fertigstellen zu können.
  • Auf der ersten Kundenpräsentation macht der Kunde eine Kombination von Mausklicks, an die die Programmierer nicht gedacht haben, und das Programm stürzt grausam ab. Es dauert zwei weitere Wochen, bis ein einfacher Bug gefunden ist, weil die Codequalität wirklich grauenhaft ist.
  • 2,5 Monate über der Zeit bekommt der Kunde sein Endprodukt und merkt, dass er mit seinen Wünschen vielleicht hätte ein Bisschen deutlicher sein sollen, denn das Programm entspricht ihnen überhaupt nicht.
  • Unbenutzt endet das Programm als Sicherungskopie auf dem Dachboden, damit sein Quellcode wiederverwendet werden kann. Doch wegen der zurechtgehackten Qualität nähert sich nie jemand dem Code auch nur nah genug, um mit seinen Armen danach greifen zu können.
  • 8,5 Monate wertvolle Softwareentwicklung gehen den Bach runter.

Fehleranalyse

Die Probleme, mit denen wir uns befassen, werden hauptsächlich durch eine Reihe von falschen Auffassungen darüber verursacht, wie Softwareentwicklung funktioniert. Die Hauptursache is vor allem, dass eine Gruppe von Softwareentwicklern in den allermeisten Fällen durch eine Person geführt wird, die Betriebswirtschaft und Personalwesen studiert hat, und was diese Person tut ist, dass sie dieselben Regeln auf die Entwickler anwendet, welche sie auch auf Arbeiter anwenden würde, die versuchen ein Haus zu bauen.

Was die meisten Manager ausser Acht lassen ist, dass es schwerwiegende Unterschiede zwischen den verschiedenen Arten der Entwicklung gibt. Der erste und wichtigste Punkt ist, dass es im Gegensatz zu Häusern hier dem Kunden sehr schwer fällt, sich das Endprodukt vorzustellen, und logischerweise ist es deshalb auch sehr schwer für ihn, sich bestimmte Anforderungen auszudenken. Es ist einfach für den Kunden festzustellen, dass das Produkt nicht seine Erwartungen trifft, aber es ist sehr schwer herauszufinden warum. Deshalb ist es absolut notwendig, sich während des Entwicklungsprozesses fest an die Softwarespezifikation des Kunden zu klammern, sodass es keine Unkosten bei der Produktion gibt, durch Dinge, die der Kunde nicht wünscht, und für die er logischerweiser auch nicht zahlt.

Eine weitere Sache, die die Modelle aussen vor lassen, ist der Verstand des Entwicklers. Die meisten Entwickler sind verspielte Wesen, und die meisten der Entwickler sind Menschen. Als solche haben sie Probleme, ihre Gedanken um Dinge zu fassen, die mehr als ein paar Bildschirmseiten lang sind. Auch hängt die Qualität ihrer Produkte sehr von ihrer Stimmung ab, und die meiste Zeit machen sie Fehler oder implementieren obskure Hacks, die sie nicht sehen. Dies ist der Grund, warum Simplizität und paarweise Programmierung so wichtig ist.

Schlussfolgerungen

Es gibt eine Reihe logischer Schlüsse aus dieser Reihe von Problemen zu ziehen. Die philosophische Auswertung dessen folgt im nächsten Kapitel, ich werde also nur die Kernpunkte hier aufzeigen:

  • Sprich mit deinem Kunden. Wenn der Kunde die Möglichkeit hat, den Fortschritt zu sehen und zu verfolgen, wie das Projekt wächst, mehren sich auch seine Chancen, zu entscheiden, was genau er mag und was nicht. Ausserdem bekommen Kunden, die aus einem Vertrag bloss so viele Produkte wie möglich herausbekommen wollen, keine Chance, weil sie sehr spezifische Empfehlungen geben müssen.
  • Unterstütze die Einfachheit. Es ist sehr schwer, die Dinge so einfach wie nur möglich zu gestalten und nicht einfacher. Allerdings ist dies äusserst notwendig bei der Softwareherstellung. Der Trick dabei ist, das Programm in viele Einzelteile zu gliedern, sodass man es einfach weitergeben kann. Diese kleinen Einheiten können dann in Form eines Bausatzes zusammengefügt werden, um ein ganzes, komplexes Programm zu ergeben. Der Versuch, diese Einheiten so zu entwerfen, dass sie zusammenwirken, ist jedoch grössenteils der direkte Weg in die Verdammnis, weil der Aufwand sehr schnell dazu neigt, ausser Kontrolle zu geraten.
  • Halte die Tests in Gang. Schreibe keinen Code, bevor du einen Test hast, der scheitert. Bringe immer die Anforderungen deines Kunden in einen Test ein, der dann fehlschlagen wird, weil das Verfahren noch nicht implementiert ist. Setze dann die präziseste Implementierung um, die dir eventuell einfällt, und höre mit dem Coden auf, sobald du den Test bestehst, denn mehr Code wird nicht gebraucht und niemand wird dich für mehr Code bezahlen. Halte die Tests aber dennoch in Gang! Wenn Wechselwirkungen mit anderem Code deine Anforderungen zunichte machen, musst du das sofort merken und es reparieren, weil du dafür bezahlt wirst, dich an die Anforderungen zu halten.
  • Fördere paarweise Programmierung. Während eine allein arbeitende Person ihre Zeit effektiver nutzt, neigen zwei Personen, die zusammen arbeiten, zu einer höheren Qualität des Quellcodes, die einen erheblichen Vorteil bezüglich der Zeit bringt, die in die Wartung investiert wird. Ein weiterer Grund ist, dass paarweise Programmierung sicherstellt, dass es immer eine zweite Person gibt, die Erfahrung hat, ein Problem zu lösen, falls eine Person allein an einem Problem scheitert. Es muss auch nicht unbedingt an einem Missgeschick oder was auch immer liegen, es könnte ebenso gut der Konkurrent sein, der einen deiner Angestellen einsetzt, um deine Produkte zu sabotieren.
  • Passe deinen Betriebsplan immer wieder an. Es ist unmöglich, immer im Voraus zu sagen, wieviel Arbeitzeit Programmierer während des Projekts in Anspruch nehmen dürfen, sodass man mit einem Voreinteilungsplan viele Unterbrechungen, Überlastungen und Leute mit Leerlauf hat. Am besten ist es da wahrscheinlich, einen Stapel Aufgaben auszuteilen, und jedes Team, das seine Arbeit verrichtet hat, nimmt sich einfach die nächste Aufgabe vom Stapel. Dies gewährleistet eine preiswerte automatisierte Zeiteinteilung.

Die Geschichte der Softwareentwicklung

Vielleicht sollte ich vorweg sagen, dass ich meine Überlegungen auf Softwareprogrammierung mit Software beschränkte, drum werde ich nicht in aller Einzelheit auf Lochkarten eingehen.

In den ganz frühen Jahren war Softwareentwicklung den Studenten und Professoren in Universitäten vorbehalten. Meistens studierten sie Mathematik oder Physik und nutzten die Maschinen für ihre Berechnungen. Zu dieser Zeit war der Code meist für Lochkarten zugeschnitten und deshalb sehr schwer zu entziffern. Leute, die es vermochten, den Code ohne besondere Mühe zu übersetzen, waren auch in der Lage, den Code zu warten, weil er für gewöhnlich ziemlich kurz ausfiel.

Endlich und zum ersten Mal gab es Ideen, Betriebssysteme für Computer zu schaffen, im Grunde genommen universelle Programme, die es einem ermöglichten, eine Vielfalt von Dingen zu erledigen, ohne alles selbst implementieren zu müssen.

Doch je mehr Dienste ein Betriebssystem für einen ausführt, desto mehr Leute werden es von ihm erwarten. Für diese Strategie war das MULTICS Betriebssystem das perfekte Beispiel geworden: Anstatt nach Einfachheit zu streben, war es ein Versuch, alle Komponenten zu integrieren und sie so zugestalten, dass sie zusammen arbeiteten. Das Endergebnis war ein grosses Chaos, das man nur mit Mühe warten konnte.

Dies brachte zwei Studenten, Ken Thompson und Dennis Ritchie, zu dem Schluss, «Softwarearchitektur ist Mist». Sie liessen sich daraufhin ein Betriebssystem einfallen, welches nur eine allgemeine Schnittstelle zu den Geräteanschlüssen bereitstellte, sich um das Timesharing kümmerte und eine perfekte Abstraktion der Prozesse hergeben sollte. Die Implementierung der Systemschnittstelle ermöglichte es den Leuten, Prozesse als komplett voneinander getrennte Dateneinheiten zu betrachten, und sie zu nutzen, um diese kleinen Dateneinheiten zu grossen Produkten zu zusammenzufügen.

Ihr Betriebssystem war ein grosser Erfolg, vor allem weil es zu jener Zeit das einzige Betriebssystem war, das auf vielen verschiedenen Architekturen laufen konnte, die damals erhältlich waren - von der PDP bis zur Honeywell DDP -, und diese mit einer einheitlichen API ausstattete.

Zu dieser Zeit blieb die Anzahl der verfügbaren Betriebssysteme konstant klein. Andere kommerzielle Systeme kamen und gingen, und die Produktion des Plan9 Operating System der Bell Labs fing sehr schnell an zu stagnieren, weil der enorme Erfolg des simplistischen UNIX alle möglichen Ressourcen lockte. Nur das UNIX Derivat der Universität Berkeley, die Berkeley System Distribution, machte eine stetige Entwicklung durch, weil es die systematische Einfachheit und zudem eine Unabhängigkeit der Entwicklung bot, den viel zitierten Flair der «Freien Software».

Eine Menge andere Betriebssysteme wurden zu der Zeit verfasst, aber nur wenige konnten es über die ersten paar Jahre hinweg schaffen. Eines von ihnen war das Virtual Memory System (VMS) für den PDP-Nachfolger VAX, benannt nach seiner virtuellen Adresserweiterung (Virtual Address Extension), welches ebenfalls ein eher einfacher Entwurf von DEC war, einer Firma, die einen unsterblichen Ruf für das kompromisslose Design sowie die Stabilität ihrer Hardware besitzt. Der DEC Enhanced VAX Prozessor (EV, auch als Alpha bekannt) war ein kompromissloser RISC Prozessor, wiederum eine Bauart, welche die Simplizität unterstützt. Der Alpha Prozessor bleibt bis zur Gegenwart in Sachen Zuverlässigkeit und Performanz unschlagbar.

Das andere Betriebssystem, welches zu der Zeit geschaffen wurde und welches bis in die Gegenwart überlebte, war das SunOS, das heutige Solaris. Es entwickelte sich aus dem UNIX System V und ist als solches ein weiteres Beispiel des Simplizismus. Über die Zeit hinweg floss viel der BSD-typischen Software in Solaris ein, das es im Grunde nur zu einem weiteren kommerziellen BSD werden liess.

Während der späten 80er und frühen 90er entstand eine andere Reihe von Betriebssystemen, die heute immernoch unser Leben beeinflussen. Eines von ihnen war das berühmte MacOS, ein Betriebssystem das oft mehrere Male vor den Veröffentlichungen umgeschrieben wurde. Im 10ten Release wurde es jedoch durch ein Microkernel-BSD ersetzt, sodass selbst in diesem Fall der Simplizismus der UNIX-artigen Betriebssysteme sich durchsetzte.

Ein anderes System, das hochkam, ist Linux. Nun hat Linux ein sehr eigenartiges Konzept: Während grosse Teile des Userlands einfach UNIX sind und als solche das Prinzip der Einfachheit unterstützen, sind seine zwei wichtigsten Bestandteile massive Codestücke, die sich nur schwerlich warten lassen: Der Kernel und die C-Bibliothek (libc). Während der Kernel bloss versucht, dem Prinzip seines eigenen Designs gerecht zu werden, deshalb sehr fragil ist und die Tendenz aufweist kaputtzugehen, hält sich die libc an das Prinzip der Einfachheit bis zu einem gewissen Grad: Ihre Fähigkeit, auf verschiedenen Systemen zu funktionieren, hat jedoch seinen Tribut gefordert und so fällt es einem es sehr schwer, die Funktion ausfindig zu machen, in der ein Bug wirklich ist.

Das letzte zu nennende System ist ein Kandidat der aussterbenden Reihe konstruierter Betriebssysteme: Windows. Das Betriebssystem selbst ist eine riesige Ansammlung von Komponenten aus Produkten anderer Firmen, die auf die eine oder andere Art zusammengekleistert sind. Microsoft schreibt lediglich den Kleistercode und merzt die Bugs im Code aus. In einigen Fällen ist Microsoft damit allerdings nicht sehr schnell, sodass zum Beispiel ein Bug in der TCP-Steuerungsroutine, der bereits Jahre zuvor in BSD im Wesentlichen behoben wurde, bei Windows mit aller Kraft einschlug.

Windows ist für seine Instabilität bekannt, und unter den Entwicklern wird es als ein grosses, kaputtes Stück Code angesehen, das nur schwerlich instand gehalten werden kann. Aus dem Grund gab es 1996 den Versuch, es komplett neu zu schreiben, und momentan (2005) findet ein weiterer Versuch statt. In der Regel rührt Microsoft jedoch den gesamten alten Basiscode aus Kompatibilitätsgründen wieder zurück unter ihren Code, sodass man meist mit all den alten Bugs konfrontiert wird, zuzüglich ein paar neuer. Der aktuelle Basiscode ist jedoch für seine Bugs bekannt und braucht alle Tage wieder einen wichtigen Sicherheitspatch, es ist also relativ klar, dass dies bereits ausser Kontrolle geraten ist.

Was wir hier also hauptsächlich erkennen können ist, dass nur UNIX und VMS die Jahrzehnte der Computer überlebt haben, und während alle anderen Systeme ihre Bestrebungen immer wieder von Neuem aufnehmen mussten, konnte das UNIX Betriebssystem sich mit der Kraft von Millionen von Händen auf der ganzen Welt einfach frei entfalten. Während Manager sich eine Vielfalt von verschiedenen Konzepten für Software und ihre Umsetzung ausdachten, stützte sich das einzige Konzept, das sich wirklich durchsetzen konnte, auf die vollkommene Beugung aller Geschäftsmethoden in der Softwareentwicklung. In den Ohren der grossen Konzerne klangen diese jedoch logisch, auch wenn sie auf dem Gebrauch der Regel «Softwarearchitektur ist Mist» fussten, die mit aller Anstrengung zu einer ganzen Religion ausgebaut wurde. Apples MacOS X ist der endgültige Beweis, dass selbst Konzerne diese Botschaft heutzutage noch schlucken.

Dasselbe steht dem Markt für Softwareentwicklungsmodelle bevor. Während das Management sich ein Entwicklungsmodell nach dem anderen ausheckt, wird das einzige durchgehend angewandte Modell Extreme Programming bleiben. Und wieder einmal ist es die Botschaft «Softwareentwicklungsmodelle sind Mist», welche zu einem Regelsatz erweitert wurde, den die Leute befolgen sollten, wenn sie gute Software schreiben wollen. Dieser Ansatz lässt es weniger nach Anti-Management aussehen. Nichtsdestotrotz kann nicht geleugnet werden, dass dieses Modell von technisch begabten Leuten entworfen wurde: Es ist sehr stark skalierbar, sogar bei geringem Overhead. Es hat all die typischen Eigenschaften, die UNIX auf dem Softwaremarkt besitzt.

Schlussfolgerungen

Die Schlüsse, die wir daraus ziehen können, wurden bereits so ziemlich in der Analyse angeführt. All die verschiedenen Softwareentwicklungsmethoden, die Manager sich immer wieder ausdenken werden, helfen der Situation keineswegs auf die Sprünge. Die Entwicklergemeinde hat schon eine gute Art gefunden, sich ganz allein zu organisieren, und da letztendlich sie die Leute mit der technischen Fachkenntnis sind, sollte das Management ernsthaft einen tiefen und genauen Blick auf die vorgeschlagene Praktik werfen.

Als Ken Thompson und Dennis Ritchie UNIX erschufen, wurden sie auch von vielen Professoren und Managern verlacht. Simplistische Herangehensweisen werden meist als ein Zeichen von Schwäche interpretiert und geben Produkten den Beigeschmack, für Kinder gemacht worden zu sein. Dennoch ist Simplizität ein sehr entscheidener Schritt im Entwicklungsprozess, vor allem auf dem Softwaremarkt, wo es aus technischer Sicht keine Notwendigkeit ist, kleine Funktionseinheiten zusammenzuschachteln.

Simplizität ist einfach kein Zeichen von Schwäche. Es ist vielmehr ein Eingeständnis einer der grundlegenden Eigenschaften des menschlichen Geistes. Wir sind unfähig mit beliebig komplexen Systemen umzugehen, und solange wir diese Tatsache nicht anerkennen, werden wir nicht in der Lage sein, beliebig komplexe Aufgaben zu lösen.

Eine Auswertung der modernen Entwicklungsmethoden

Dieser Abschnitt gibt eine kurze Übersicht über aktuelle Entwicklungsmodelle und deren genaue Kredos.

Domain Specific Modelling

Das Domain Specific Modelling (Domänenspezifische Modellierung) ist das von Microsoft bevorzugte Entwicklungsmodell, einer sehr erfolgreichen Softwarefirma. Gleichwohl ist es eine allseits bekannte Tatsache, dass selbst mit diesem Entwicklungsmodell Microsoft noch nicht im Stande war, mit ordentlicher Software aufzuwarten. Wir wollen trotzdem erst einmal einen Blick darauf werfen, bevor wir voreilige Schlüsse ziehen.

Die grundlegende Idee hinter Domain Specific Modelling ist die der Softwareentwicklung anhaftenden Komplexität, die im Implementierungsprozess nicht vermieden werden kann. Gleichzeitig müssen die Programmierer sehr produktiv sein; somit ist das erklärte Ziel des Domain Specific Modelling, es den Entwicklern zu erlauben, mit der Komplexität fertigzuwerden, indem man gewissermassen ihren Informationsaustausch mit Experten des Gebiets optimiert, mit dem sich sie gerade beschäftigen. Dafür werden sogenannte bereichseigene Sprachen (Domain Specific Languages) entwickelt, die für den freien Informationsaustausch von Softwareingenieuren und dem System selbst benutzt werden können, mit Bereisexperten, die keine Ahnung von Softwaretechnik haben.

Dieses Modell geht davon aus, dass das grösste Problem kommerzieller Softwareentwicklung ein Missverständniss zwischen Technikern und Experten ist und dass dieses Problem auf eine technische Art gelöst werden kann. In der Realität sieht das allerdings so aus, dass die Entwicklung einer bereichseigenen Sprache ein abstrakter Prozess ist, der für alles neu definiert werden muss, was eine der beiden Parteien sagt. Roger Penrose schrieb in seinem Buch «Computerdenken» (orig.: The Emperor's New Mind), es sei unmöglich, das gesamte menschliche Gehirn durch eine Maschine zu reproduzieren, denn die Quantenphysik besagt unter anderem, dass es immer einen möglichen Ablauf gibt, den die Programmierung der Maschine nicht berücksichtigt und mit dem sie folglich nicht umgehen kann.

Während die Entwicklung einer vollständigen bereichseigenen Sprache also unmöglich ist, erweist sich die Entwicklung einer Teilsprache aus demselben Grund als äusserst ineffizient: Der Entwickler muss ein System herstellen, das jeden Schritt des Experten interpretiert - was im Grunde sein Gehirn bereits tut. Es wäre also wesentlich einfacher, bloss das Gesagte des Expertren zu notieren und es auszuwerten.

Ein weiteres Problem ist, dass Kunden in der Regel nicht wissen, was sie wollen. Was sie also zu Begin eines Entwicklungsprozesses sagen, könnte zum Schluss keine oder eine gänzlich andere Bedeutung haben, abhängig davon, was der Kunde im Verlauf des Prozesses hinzufügt. Es wäre unmöglich, das vorauszusehen.

Design Patterns

Design Patterns (Entwurfsmuster) sind eine ganz einfache Idee. Üblicherweise behalten Experten die Lösungen für ihre Probleme, um sie später wiederverwenden zu können, wenn ein ähnliches Problem auftaucht. Doch wird die Idee, spezielle Verzeichnisse für Entwurfsmuster und alles andere zu haben, viel zu sehr überbewertet, zumal es bereits Implementierungen dafür gibt, und zwar genau in der guten alten Software an sich: Shared Libraries (Gemeinsame Funktionsbibliotheken).

In diesem Sinn ist das Internet eine riesige Ansammlung von Entwurfsmustern. Es gibt viele Funktionsbibliotheken über den ganzen Planeten verteilt und voraussichtlich hat bereits jemand dein Problem gelöst und ein solches Pattern, eine Funktionsbibliothek, geschrieben. Zum Beispiel gibt es für Perl-Code CPAN, wo die Leute Perl-Module für so ziemlich alles herunterladen können.

Natürlich könnte jemand argumentieren, dass Design Patterns eine sehr abstrakte Sache sind und in verschiedene Programmiersprachen konvertiert werden könnten, wohingegen Funktionsbibliotheken im Grunde genommen zugeschnitten auf die Programmiersprache sind. Dagegen spricht, dass man nicht jede Programmiersprache auf diesem Planeten braucht, um ein Problem zu lösen. Tatsächlich gibt viel zu viele Programmiersprachen, die keinen besonderen Nutzen gegenüber all den anderen bringen, ausser dass man sich dadurch aus einem riesigen Datenpool vorhandener Lösungen aussperrt. Auf der anderen Seite ist es keine Schande, sich auf drei oder vier Hauptprogrammiersprachen zu beschränken, die für die meisten Probleme Implementierungen haben werden. Dies ist weitaus nützlicher als abstrakte Entwurfsmuster.

Der Rational Unified Process

Die Grundannahme des vereinheitlichen rationellen Prozesses (Rational Unified Process) ist, dass Softwareentwicklung in vier verschiedene Entwicklungsstufen unterteilt werden kann, die immer nacheinander folgen und keine Wechelswirkungen haben: Die Unterbrechungsphase, in der Ziele skizziert und Ressourcen zugeteilt werden, die Ausarbeitungsphase, in der Probleme analysiert werden, die Aufbauphase, in der ein Fertigprodukt implementiert und getestet wird, und die Übergangsphase, wenn der Endbenutzer das Produkt beurteilt und entscheidet, ob es das ist, was er möchte.

Dieses Modell hat das Problem, dass es unmöglich ist, dem nachzukommen. Für gewöhnlich tritt die Unterbrechungsphase dann ein, wenn dein Kunde dir mitteilt, was er will, und die Ausarbeitungsphase ist, wenn dein Denkapparat ausarbeitet, was dabei zu tun ist. Dann begibt man sich in die Aufbauphase, man schreibt seinen Code und erledigt exakt die Aufgabe, die einem in der Unterbrechungsphase zuteil wurde.

An diesem Punkt wird man schon die meiste Zeit damit konfrontiert, dass einige Leute viel mehr und viel schwierigere Probleme zu lösen haben als andere, weil die Zuteilung der Ressourcen schon geschah, bevor der Arbeitsumfang pro Person geschätzt werden konnte. Dies ist kein Horrorszenario, aber es bereitet den Angestellten Unbehagen, weil es dann die eine Gruppe gibt, die den Eindruck hat, eine andere Gruppe sei zu langsam, und eine andere Gruppe von Leuten, die denken, die andere Gruppe hätte nichts zu tun. Das erzeugt wiederum Unzufriedenheit.

Dann begibt man sich in die Übergangsphase, wo einem klar wird, dass das Produkt, welches man soeben auf den Markt geworfen hat, so ganz und gar nicht den Erwartungen des Kunden entspricht. Meistens sind die Diskrepanzen gravierend genug, dass man das ganze Projekt beinahe von Neuem beginnen und das ganze Zeug nochmals entwerfen muss. Das heisst, dass man nur ein weiteres Stück Software geschaffen hat, das am Ende keiner braucht.

Ein guter Vergleich zu dieser Situation ist es, wenn man von Lausanne nach Luzern kommen will. Beim RUP muss man in die Richtung zeigen, wo man denkt, dass Luzern ist, und den nächsten Zug nehmen, der in die Richtung abfährt. Dann muss man allerdings bis zur Endstation auf diesem Zug bleiben, und nun darf man erst fragen, wo man sich eigentlich befindet. Dies ist dann vermutlich St. Gallen, das meilenweit vom Reiseziel entfernt ist. Und so wird man wieder die Richtung suchen und den nächsten Zug nehmen müssen, und mit etwas Pech kommt man wieder zurück nach Lausanne. Doch wenn man Glück hat, kommt man Luzern wenigstens etwas näher.

Das ist eine effiziente Art, durch die gesamte Schweiz zu reisen, aber sie ist nicht effizient, man so schnell wie möglich nach Luzern zu kommen versucht.

(Was in der Welt der Softwareentwicklung ein zusätzliches Problem darstellt ist, dass Kunden dazu neigen, sich ihrer Wünsche nicht allzu sicher zu sein, wie bereits gezeigt wurde. So bleibt man also dabei, die ganze Schweiz zu durchqueren, auf der Suche nach einem bewegten Ziel, indem man einfach auf die Züge achtet, von denen man denkt, sie gingen in die richtige Richtung.)

Zudem fördert das RUP-Modell die Nutzung von UML-Diagrammen, mit denen man seinen Programmen Ausdruck verschaffen kann - was vollkommen unsinnig ist. Alles, was man dadurch bekommt, ist eine zusätzliche Komplexitätsschicht, die man ohnehin umgehen muss, sobald man sein Programm kompiliert. Denn dann muss man auf den entstandenen Code schauen, um die Bugs zu fixen, was man ohnehin tun wollte, abgesehen von der Tatsache, dass man sich nun in seinen eigenen Code einarbeiten und bereits jede Menge Zeit verschwendet hat. Auch sind UML-Diagramme wirklich kaum lesbarer als gut geschriebener Code in C. Und wenn man auf dem Gebiet nicht bewandert ist, kann man ohnehin beides nicht lesen.

V-Model XT

Das V-Model XT ist im Grunde genommen eine erweiterte Form des RUP. Es versucht, die unvermeidbaren Probleme des RUP zu meiden, indem es die charakteristischen Probleme des RUP-Vorgangs durch die Bildung einer selbst-lernenden Einrichtung löst, die effizient lernen soll, wie man die Probleme umgeht, an die man während der RUP-Projekte geraten ist. Doch daraufhin bekommt die Einrichtung ein neues Projekte und gerät an dieselben Probleme.

Extreme Programming

Das Extreme Programming (XP) ist ein Softwareentwicklungsmodell, das von Computergeeks in den 80ern erfunden wurde. Es basiert auf einigen Annahmen:

  • Kunden wissen nicht, was sie wollen. Deshalb muss man den Kunden nach seinem aktuellen Wunsch fragen und implementiert diesen mit so wenig Aufwand wie möglich. Daraufhin geht man zurück zum Kunden, um ihn nach seiner Meinung zu dem kleinen Stück Software zu fragen, das man ihm vorgelegt hat. Dies hat den Nebeneffekt, dass der Kunde jeweils nur ein bestimmtes Produkt bekommt, anstatt zu sagen, «Das ist nicht, was wir wollten, nun machen Sie bitte etwas anderes.»
  • Programmierer kommen nur mit wenig Komplexität zurecht. Deshalb muss jedes Problem in seine kleinsten Einheiten gegliedert werden, die dann einzeln implementiert werden können. Die Implementierung dieser Einheiten kann unter beteiligten Teams verteilt werden, während man zu viele Themenwechsel für die Teams vermeidet.
  • Programmierer neigen dazu, Dinge zu verkomplizieren. Deshalb ist es notwendig, einen Test zu schreiben, bevor man sich an den eigentlichen Code macht, der das Problem lösen soll. Sobald der Code den Test besteht, muss der Programmierer aufhören, Code zu schreiben.
  • Programmierer neigen dazu, Dinge kaputtzumachen. Deshalb muss eine Problemeinheit ihre Tests immer am Laufen halten, um sicherzugehen, dass Änderungen an einer Stelle keine Folgen an anderer Stelle nach sich ziehen. Dies sollte auch Speicherüberläufe umfassen.
  • Programmierer neigen dazu, schwer zu wartenden Code zu produzieren. Deshalb ist es notwendig, dass immer zwei Programmierer an einem Stück Code arbeiten. Die beiden sind ein Kompromiss zwischen drei Problemstellungen: Das unbedeutendere Problem ist die Verschwendung von Ressourcen, und die weiteren Probleme sind die Codequalität, die dank der zweiten Person erheblich ansteigt, für die der Code lesbar bleiben muss, sowie die Wissensvermittlung: Falls einem der Entwickler etwas zustösst, kann der zweite das Projekt immernoch ohne viel Verzögerung fertigstellen.
  • Man kann nicht Ressourcen, Zeit, Qualität und den Umfang eines Projekts gleichzeitig kontrollieren. Deshalb muss man den unbedeutendsten Faktor reduzieren: Den Umfang.