19.3.2026
Deutsch · English
Softwareentwicklung verändert gerade ihre grundlegende Natur.
Eine hilfreiche Perspektive darauf kommt aus der Theory of Constraints, entwickelt von Eliyahu M. Goldratt.
Theory of Constraints im Kern
Die Grundidee ist überraschend simpel:
In jedem System gibt es meist eine dominante Engstelle, die den Durchsatz bestimmt.
Verbessert man diesen Engpass, verbessert sich das gesamte System.
Und wenn er verschwindet, taucht er an anderer Stelle wieder auf.
Fortschritt besteht deshalb oft nicht darin, Systeme einfach schneller zu machen.
Fortschritt bedeutet, den Engpass zu verschieben.
Goldratt formulierte daraus einen iterativen Prozess:
- Constraint identifizieren
- Constraint maximal ausnutzen
- Alles andere darauf ausrichten
- Constraint erweitern
- Zurück zu Schritt 1 (weil sich der Engpass verschiebt)
Jede ernsthafte Verbesserung eines Systems besteht letztlich darin, diesen Engpass bewusst zu verlagern.
In Wissensarbeit kann dieser schnell wechseln oder fragmentieren.
Interessanterweise hilft diese Perspektive auch, eine der einflussreichsten Ideen der Softwareentwicklung neu zu verstehen.
XP als Engpass-Verschiebung
Als Extreme Programming Ende der 90er entstand, lag das Radikale nicht in einzelnen Praktiken wie Pair Programming, Test-Driven Development oder Simple Design.
Das Radikale war das Systemdenken.
XP funktionierte, weil sich seine Praktiken gegenseitig verstärkten.
XP war kein Werkzeugkasten.
Es war ein zusammenhängendes System von Praktiken, das darauf ausgelegt war, den Durchsatz eines Teams unter Unsicherheit zu maximieren.
Im Kern war XP ein Versuch, die dominanten Engpässe in der Softwareentwicklung systematisch zu stabilisieren.
Das Ergebnis war ein Entwicklungsprozess, der Änderungen dauerhaft möglich halten sollte.
Der Engpass verschiebt sich erneut
Mit generativer KI verändert sich diese Landschaft erneut.
Und radikal.
Große Sprachmodelle reduzieren viele Aufgaben, die lange Zeit einen erheblichen Teil der Entwicklungsarbeit ausmachten.
Modelle können Code generieren, Varianten vorschlagen und Lösungsräume erkunden.
Coding Agents gehen noch einen Schritt weiter.
Sie können selbstständig ganze Entwicklungszyklen automatisieren.
Damit verändert sich nicht nur die Geschwindigkeit.
Es verändert sich die Struktur des gesamten Systems.
Die technische Umsetzung ist nicht mehr automatisch der limitierende Faktor.
Der Engpass liegt zunehmend an anderen Stellen:
-
Problemformulierung – Was bauen wir eigentlich?
-
Designentscheidungen – Welche Struktur trägt langfristig?
-
Evaluation – Ist eine generierte Lösung wirklich gut?
-
Verständnis – Kann das Team den Code noch erklären?
Der limitierende Faktor wird zunehmend kognitiv und koordinativ.
Was das für XP bedeutet
XP bewegt sich vom Schwerpunkt Coding hin zur kollektiven Kognition.
Wenn sich der Engpass verschiebt, verschiebt sich auch die Funktion der Praktiken.
Einige werden zentraler.
Einige verändern ihre Rolle.
Und einige entstehen erst jetzt.
Der neue Engpass: menschliches Verständnis
Pair Programming
Cognitive Triad
Pair Programming verbindet zwei Perspektiven:
„Driver“ schreibt Code, „Navigator“ behält Struktur und Design im Blick.
Mit großen Sprachmodellen entstehen neue spannende Konstellationen.
Modelle sind starke Sparringspartner.
Sie können Code vorschlagen, Varianten diskutieren, Lösungsräume explorieren.
Aber sie verstärken auch Confirmation Bias.
Kritische Reflexion kann abnehmen.
Falsche Annahmen skalieren schneller als je zuvor.
Mit Coding Agents verändert sich diese Dynamik weiter.
Werkzeuge können selbstständig Code schreiben, Tests ausführen und Änderungen als Pull Requests vorschlagen.
In der Extremform entwickelt sich Pair Programming zu einer kognitiven Triade:
Customer — Developer — Model.
Agenten machen die engst mögliche Kopplung plötzlich operational.
Der Kunde bringt Problemverständnis.
Der Entwickler verantwortet Systemstruktur und Kontext.
Das Modell übernimmt Umsetzung und Exploration.
Der Entwickler wird weniger „Driver“ und stärker „Navigator“ eines Systems, das ganze Lösungsräume ausarbeitet und in großen Strukturen materialisiert.
Die Spannung zwischen diesen drei Rollen erhöht die kollektive Intelligenz – genau das ursprüngliche Ziel von Pair Programming.
Collective Code Ownership
Radical Code Transparency
Collective Ownership bedeutet:
Jeder darf alles ändern.
Mit Coding Agents wird diese Idee radikalisiert.
Ein Agent mit Projektzugriff kann alles verändern, aber nur innerhalb der System-Constraints.
Code entsteht zunehmend in orchestrierten Prozessen.
Collective Ownership mit einer Maschine.
Autorschaft verliert an Bedeutung.
Entscheidend wird stattdessen kollektives Verständnis.
Mit dem Ziel:
Maximale Reduktion von Black-Box-Risiko.
Collective Ownership wird zu radikaler Code-Transparenz.
Wenn Code jederzeit durch Menschen oder Agenten verändert werden kann, muss seine Struktur und Motivation für alle nachvollziehbar bleiben.
Im Limit verliert Code seinen Status als langlebiges Asset.
In vielen Fällen ist es effizienter, Code neu zu erzeugen, als bestehenden Code zu ändern.
Damit wird Code austauschbar.
Zwei Implementierungen sind gleichwertig, solange sie im selben Kontext entstehen und dieselben Tests erfüllen.
Das System besitzt keinen Code mehr – es besitzt stattdessen die Fähigkeit, ihn jederzeit neu zu erzeugen.
Kontrolle über ein driftendes System, das Code erzeugt
Test-Driven Development
Behavior-First Engineering
Tests waren schon immer Spezifikation.
Mit generativer Programmierung werden sie zur Steuerschnittstelle.
Coding Agents können Code erzeugen, verändern und neu strukturieren.
Aber sie brauchen klare Grenzen für akzeptables, erwartetes Verhalten.
Test-First erfüllt genau diese Funktion.
Tests definieren das gewünschte Verhalten vor der Implementierung und werden somit zum Vertrag zwischen Mensch und Maschine.
In einer agentischen Entwicklungsumgebung werden Tests zur Programmiersprache, mit der wir Coding Agents steuern.
Der Agent kann Tests lesen, schreiben, ausführen und seine Implementierung so lange anpassen, bis Tests grün sind.
Die klassische TDD-Schleife, nur dass ein Teil davon automatisiert wird.
Damit verschiebt sich die Hierarchie:
Tests werden zum Primärartefakt.
Code wird zur Ableitung.
TDD wird somit noch zentraler, zu verhaltensorientierter Entwicklung.
Es stabilisiert ein probabilistisches System gegen Drift – also gegen das schleichende Auseinanderlaufen von Verhalten unter scheinbar gleichen Bedingungen.
Continuous Integration
Continuous System Verification
Continuous Integration sorgt dafür, dass Integrationsprobleme früh sichtbar werden.
Mit generativer KI steigt jedoch die Änderungsrate erheblich.
CI wird zum Immunsystem.
Neben klassischen Tests prüfen Pipelines zunehmend auch, ob grundlegende Systemeigenschaften stabil bleiben.
In einem System, das durch generative Modelle verändert wird, entsteht eine neue Gefahr:
probabilistische Drift.
Kleine, lokal korrekte Änderungen können das System schrittweise von seiner ursprünglichen Struktur und Semantik wegbewegen.
CI wird zum Mechanismus, diese Drift sichtbar und kontrollierbar zu machen.
Da Änderungen schneller und in größeren Einheiten entstehen, wächst auch ihr potenzieller Impact.
Den Blastradius zu begrenzen wird zentral.
XP kannte schon immer Acceptance Tests als Schnittstelle zum Kunden.
In einer agentischen Entwicklungsumgebung entsteht eine ähnliche Struktur innerhalb des Teams:
Continuous Integration wird zum Akzeptanztest für den generierten Code, zu kontinuierlicher Systemverifikation.
Das Entwicklungsteam definiert die Kriterien, die ein System erfüllen muss, bevor es als verstanden und integrierbar gilt.
Designstrategie für eine Welt extrem billigen Codes
Refactoring
Continuous Code Assimilation
Refactoring hält Software soft – langfristig.
Im Zeitalter generativen Codes ist Refactoring nicht mehr Aufräumen.
Es ist Entropiekontrolle.
Modelle erzeugen funktionierenden Code, doch selten ein kohärentes Design.
Unterschiedliche Patterns, redundante Abstraktionen und inkonsistente Strukturen entstehen parallel.
Refactoring wird zum kontinuierlichen Assimilationsprozess.
Generierter Code wird nicht einfach übernommen, sondern aktiv in die Architektur integriert.
Erst durch Refactoring übersetzt das Team maschinell erzeugtes Rohmaterial in sein Systemverständnis.
Das Refactoring hilft, generierten Code zu verdauen.
Coding Agents verstärken diese Dynamik weiter.
Große strukturelle Änderungen, die einst Tage kosteten, lassen sich mit agentischer Unterstützung in Minuten durchziehen.
Refactoring wird von einer knappen Ressource zu einer billigen Operation und fast kontinuierlichen Aktivität.
Damit solche Systeme stabil bleiben, gewinnen klare Kontextgrenzen an Bedeutung.
Konzepte wie Core Models und Bounded Contexts helfen, Systeme in Einheiten zu strukturieren, die sich unabhängig verstehen, generieren und neu zusammensetzen lassen.
Sie schaffen Inseln, in denen generativer Code beherrschbar bleibt –
mit begrenztem Blastradius und einer Komplexität, die sowohl für Menschen als auch für Modelle im Kontext bleibt.
Gleichzeitig entsteht eine neue Gefahr:
Wenn Veränderung zu billig wird, steigt die Versuchung, Struktur permanent zu verschieben, ohne sie wirklich durchdrungen zu haben.
Mit generiertem Code steigt die Änderungsrate und strukturelle Konsistenz wird fragiler.
Design wird insgesamt weniger vorausschauend und stärker evolutionär.
XP hat das immer behauptet.
Agentic Coding macht es realistisch.
Simple Design
Radical Simplicity
Simple Design bedeutet: nur so viel Design wie nötig.
Im LLM-Zeitalter wird diese Praxis noch wichtiger.
Generative Systeme haben eine natürliche Tendenz zur Überkomplexität.
Sie erzeugen zusätzliche Abstraktionen, defensive Strukturen und generische Architekturen.
Generierter Code unterscheidet sich grundlegend:
Produzierter Code entsteht nicht mehr 100% aus unserer Intention heraus, sondern als Ergebnis eines probabilistischen Prozesses.
Die Aufgabe des Teams verschiebt sich.
Es geht weniger darum, Lösungen zu erfinden.
Und mehr darum, Komplexität konsequent zu entfernen.
Simple Design wird zu einer Praxis der radikalen Einfachheit –
einem Filter gegen generative Komplexität und somit zu einer der wichtigsten Fähigkeiten überhaupt.
System Metaphor
Shared Mental Model
Die System Metaphor war selbst eine Form eines generativen Modells.
Sie adressierte ein zentrales Problem:
Wie schafft man ein gemeinsames Verständnis mit ausreichend Bandbreite, um ein wachsendes System zu tragen.
Diese Funktion wird im Zeitalter generierten Codes wieder wichtig.
LLM-generierter Code kann lokal sinnvoll erscheinen, ohne global kohärent zu sein.
Unterschiedliche Teile des Systems folgen dann implizit verschiedenen Architekturideen.
Teams brauchen deshalb wieder stärker ein gemeinsames mentales Modell ihres Systems.
Erzählbare Strukturen wie Metaphern, Domänenmodelle und narrative Beschreibungen.
Eine gute Systemmetapher wirkt wie ein kognitiver Kompressionsmechanismus:
Sie macht Komplexität erzählbar.
Und somit überhaupt erst kollektiv beherrschbar.
In einer Welt mit Coding Agents wird sie zur generativen Architektur.
Coding Standards
Machine-Readable Design
Coding Standards sind nicht mehr nur soziale Konventionen.
Mit KI-generiertem Code verändert sich diese Rolle deutlich.
Code entsteht heute schneller und in größerer Menge als je zuvor.
Dabei entstehen neben Implementierungen auch zahlreiche Zwischenartefakte.
Teams müssen Systeme strukturstabil halten, obwohl ständig neues Material entsteht.
Damit wächst eine neue Gefahr: strukturelle Drift.
Coding Standards werden zu einer Form maschinell durchsetzbarer Design-Disziplin, die verhindert, dass ein System aus ständig neu erzeugtem Code seine Kohärenz verliert.
Sie sind das System Prompt des Repositories – Steuersignale für generativen Code.
Äußerer Wertschöpfungsloop: Earn or Learn
On-Site Customer
Customer-Driven Discovery
Der On-Site Customer sollte im ursprünglichen XP den Anforderungsdialog direkt ins Team bringen.
Im Zeitalter generativer KI verschiebt sich diese Rolle am deutlichsten.
Der Kunde kann heute selbst beginnen, den Problem- und Lösungsraum zu explorieren.
Mit Hilfe generativer Modelle lassen sich Szenarien durchspielen, Interaktionen testen und mögliche Lösungen skizzieren.
Auch Acceptance Tests verändern sich dadurch.
Was früher häufig ein Engpass war, kann nun test-first vom Kunden vorbereitet werden.
Mit KI-Unterstützung lassen sich Beispiele, Szenarien und Grenzfälle schnell formulieren und iterieren.
Kunde (oder Product Person) wird zum Mit-Entdecker im Suchprozess nach der richtigen Lösung.
Die alte XP-Idee der Driving Metaphor bekommt neues Momentum.
Doch in Kombination mit Coding Agents entsteht eine noch tiefere Veränderung.
Wenn Modelle aktiv an Exploration und Implementierung teilnehmen, verschiebt sich die grundlegende Einheit der Zusammenarbeit.
Das klassische XP-Paar erweitert sich zur kleinsten funktionsfähigen Einheit moderner Produktentwicklung:
Customer — Developer — Model.
Was im Pair Programming als kognitive Triade sichtbar wird, wird hier zur Struktur des gesamten Teams.
Der Kunde bringt Problemverständnis und Hypothesen ein.
Der Entwickler verantwortet Systemstruktur, Kontext und Integration.
Das Modell ermöglicht schnelle Exploration und Umsetzung.
Der On-Site Customer entwickelt sich weiter zur kundengeleiteten Exploration innerhalb einer kognitiven Triade.
Die Idee des Whole Team wird radikalisiert.
Das Team wird zu einem gekoppelten System aus Menschen und generativen Modellen, das gemeinsam den Problem- und Lösungsraum durchsucht.
On-Site Customer wird damit zu etwas, das XP immer angedeutet hat, aber selten vollständig erreicht wurde:
Der Kunde wird zum Ko-Designer eines sozio-technischen Systems, das Denken und Implementieren eng miteinander verschränkt.
Planning Game
Continuous Discovery Loop
Das Planning Game synchronisiert Entwicklung und Business.
Mit LLMs verschiebt sich der Engpass fundamental.
Implementierung wird billig.
Exploration wird skalierbar.
Teams können plötzlich mehr Lösungen erzeugen, als sie sinnvoll bewerten können.
Das eigentliche Risiko ist zu frühes Bauen.
Das Planning Game entwickelt sich zu einem kontinuierlichen Erkenntniszyklus aus Hypothesenbildung, Exploration und Lernen.
Coding Agents verstärken diese Dynamik weiter.
Sie können Experimente vorbereiten, Tests ausführen und Ergebnisse analysieren.
Das Planning Game wird teilweise automatisiert.
Entwickler planen weniger Arbeit, als sie Erkenntnisgewinn orchestrieren.
Wert entsteht nicht mehr im Schreiben von Code, sondern im Verwerfen von Möglichkeiten.
Wenn Optionen explodieren, wird Selektion zum Engpass.
Einschränkungen durchzusetzen wird zu einem zentralen Skill.
Nein wird wichtiger als Ja.
Small Releases
Micro-Experiments
Small Releases reduzieren Risiko, indem Software in kleinen Schritten ausgeliefert wird.
Mit generativer KI wird Codeproduktion extrem billig.
Features lassen sich schneller erzeugen als je zuvor.
Das neue Risiko ist Feature-Überproduktion.
Small Releases werden zu kleinen Experimenten.
Jede Änderung testet eine Hypothese über Nutzerverhalten, Systemwirkung, Produktwert.
Ein Release ist dann vor allem eines: ein Lernschritt.
Wenn Experimente billig genug werden, ersetzen sie zunehmend Diskussionen.
Ein Release kann schneller Klarheit schaffen als ein Meeting.
XP hatte diese Idee immer implizit.
Generative Systeme treiben sie nun auf die Spitze.
Nachhaltigkeit als Systeminvariante
Sustainable Pace
Sustainable Cognitive Load
XP zielte immer auf nachhaltiges Arbeitstempo.
Mit KI entsteht jedoch eine neue Versuchung:
Geschwindigkeit künstlich zu erhöhen.
Der eigentliche Engpass bleibt jedoch menschliche Urteilskraft.
KI verschiebt den Engpass in den menschlichen Kopf.
Wenn Iterationsgeschwindigkeit steigt, wachsen auch Entscheidungsdruck, Kontextwechsel, mentale Belastung.
Sustainable Pace entwickelt sich zu nachhaltiger mentaler Belastung.
XP schützt damit seine wichtigste Ressource:
menschliche Aufmerksamkeit.
Neue Muster
Neben diesen Transformationen entstehen auch neue Muster, die im ursprünglichen XP noch nicht existierten.
Ein besonders interessantes ist Disposable Code.
Wenn LLMs Prototypen extrem schnell erzeugen können, wird Code zu etwas, das man explorativ nutzt und anschließend verwirft.
Die gute alte Spike Solution wird zur Kerndisziplin.
Daraus ergibt sich ein weiteres Muster: Reconstructive Programming.
Ein generiertes System dient zunächst als Exploration.
Danach wird die eigentliche Implementierung bewusst neu aufgebaut – testgetrieben und aus Verständnis heraus.
Ein dritter neuer Aspekt ist Exploration at Scale.
LLMs erlauben es, viele Varianten eines Lösungsraums zu untersuchen.
Die Rolle des Menschen verschiebt sich dadurch von der Produktion zur Auswahl und Entscheidung.
XP-Shift durch generative KI
XP verschiebt sich systematisch entlang des neuen Engpasses – von Codeproduktion hin zu Verständnis, Entscheidung, Systemkohärenz.
| XP-Shift |
Stabilisierter Engpass |
| kognitive Triade |
Qualität von Entscheidungen |
| radikale Code-Transparenz |
kollektives Verständnis des Codes |
| verhaltensorientierte Entwicklung |
stabil definiertes Systemverhalten |
| kontinuierliche Systemverifikation |
Systemintegrität |
| kontinuierlicher Assimilationsprozess |
strukturelle Kohärenz des Systems |
| radikale Einfachheit |
kognitive Komplexität |
| gemeinsames mentales Modell |
kollektives Architekturverständnis |
| maschinell durchsetzbares Design |
strukturelle Konsistenz generierten Codes |
| kundengeleitete Exploration |
Problem-Solution-Fit |
| kontinuierlicher Erkenntniszyklus |
Problemverständnis und Problemwahl |
| kleine Experimente |
Lernen aus Nutzerfeedback |
| nachhaltige mentale Belastung |
menschliche Urteilskraft |
Warum XP gerade jetzt relevant ist
XP zielte nie primär auf Geschwindigkeit, sondern auf Stabilität unter Unsicherheit.
Genau diese Eigenschaft wird im Umgang mit generativen Systemen zentral.
Wir programmieren nicht mehr primär ein System.
Wir programmieren die Bedingungen, unter denen ein System entsteht.
Generativer Code macht einige der radikalsten XP-Ideen wieder notwendig.
XP war immer eine Methode zur Maximierung der Lernrate.
Ein System aus engen Lernschleifen und bewusst verschobenen Engpässen.
Im KI-Zusammenhang tritt dieser ursprüngliche Kern deutlicher hervor.
Generative KI erhöht die Geschwindigkeit der Exploration.
Sie vergrößert den Lösungsraum dramatisch.
XP sorgt dafür, dass Teams in diesem Raum nicht die Orientierung verlieren.
Modelle und Coding Agents erzeugen enorme Mengen Code.
Doch genau diese Produktionsmaximierung erzeugt neue Risiken.
Große Mengen Code können so schnell degenerieren wie sie generiert werden.
Ohne starke Feedbackmechanismen wächst Komplexität unkontrolliert über unsere Köpfe hinweg.
Die neuen Engpässe
Der Engpass verschiebt sich dadurch.
Während Maschinen immer schneller Code erzeugen, stabilisieren die XP-Praktiken die Ressourcen, die sich nicht einfach automatisieren lassen:
- Verstehen
- Entscheiden
- gemeinsame mentale Modelle
- kohärente Systemstruktur
Mit anderen Worten:
In einer Welt, in der Code billig wird, werden Verständnis und Urteilskraft zur knappsten Ressource.
Genau hier greifen die klassischen XP-Praktiken.
Der eigentliche XP-Shift
Extreme Programming wollte ursprünglich eine Sache erreichen:
Änderungen jederzeit billig halten.
Wenn Codeproduktion billig wird, verschiebt sich der Preis.
Dann wird Verständnis teuer.
Die neue Mission lautet deshalb:
Die Kosten des Verstehens flach halten.
Die Produktion von Code ist nicht mehr der Engpass.
Die Produktion von Bedeutung ist es.
Wenn dir dieser Text etwas gebracht hat, kannst du meine Arbeit mit einer Spende unterstützen.
Ich entwickle diese Ideen weiter und möchte daraus eine kleine Serie machen.
5.5.2005
von Frank Westphal und Tammo Freese
erschienen in der InfoWeek 09/2005
Vor noch fünf Jahren galten seine Ideen zur Softwareentwicklung als unglaublich extrem.
Heute sind viele der Extreme Programming (XP) Praktiken akzeptiert.
Mit einer von Grund auf neu geschriebenen, zweiten Auflage seines Bestsellers "Extreme Programming Explained" zeichnet Kent Beck ein aktuelles Bild:
Die vielleicht effektivste und zugleich menschlichste Softwareentwicklungsmethodik ist gerade noch effektiver und menschlicher geworden.
Das neue Extreme Programming schlägt leisere Töne an.
Die Kinderkrankheiten hat es hinter sich gebracht, es ist erwachsen geworden.
Im Kern finden sich nach wie vor die vier groß geschriebenen Werte:
Einfachheit, Kommunikation, Feedback und Mut.
Schon seit frühesten Tagen lag XP als fünfter Wert Respekt zu Grunde, der in der neuen Fassung nun explizit seinen Einzug ins Wertesystem feiert.
Mehr pragmatisch und weniger dogmatisch
Die wohlbekannten XP-Praktiken sind aus den gesammelten Erfahrungen der vergangenen Jahre sowohl verbessert, vereinfacht und konkretisiert als auch verallgemeinert worden.
Fanden sich im ursprünglichen XP nur ein Dutzend Praktiken, hat sich die Anzahl mit der Überarbeitung verdoppelt.
Der Grund zur scheinbaren Zunahme der schlanken Methode ist, dass die Menge der Praktiken jetzt in Pflicht und Kür aufgeteilt ist:
Während die primären Praktiken meist isoliert anwendbar sind und deshalb in jedem Prozess zu einer sofortigen Verbesserung führen können, setzen die weiterführenden Praktiken auf den Grundstock auf und führen den agilen Prozess schließlich an seine Leistungsgrenzen.
Nichtzuletzt durch diese Abschwächung gelingt es dem runderneuerten XP, einerseits die Eingangsschwelle für jedermann zu senken und andererseits in Anwendungsbereiche vorzudringen, für die es initial nicht geeignet schien.
Als Beispiele seien hier nur große und verteilte Projekte genannt.
Bei Programmierern beliebt
Vieles hat sich durch XP verändert:
Einige XP-Praktiken werden mittlerweile im Studium vermittelt.
Automatisiertes Testen ist zum festen Bestandteil der Entwicklungskultur geworden.
Zur inkrementellen Verbesserung des Softwaredesigns stehen Entwicklungsumgebungen mit automatisierter Refactoringunterstützung zur Verfügung.
Und Pair Programming wird heute viel einfacher akzeptiert.
Während sich das leichtgewichtige XP bislang nicht gegen schwergewichtige Prozesse durchsetzen konnte, scheint es vor allem in kleineren Unternehmen Erfolg zu haben.
Der Grund dafür ist sicherlich, dass dem vorherrschenden chaotischen "Code und Fix" Vorgehen vieler Softwareunternehmen mit XP's gesundem Menschenverstand schnell zu einem massiven Produktivitätsgewinn verholfen werden kann.
Im Management wenig Durchdringung
War XP auch die erste agile Methode, die von einer breiten Masse wahrgenommen wurde, steht ihr Bekanntheitsgrad in keinem Verhältnis zu ihrem Verbreitungsgrad.
Ganz anders sah dies aus, als das erste Buch erschien.
Zu Zeiten der Dotcom-Ära gedieh XP überaus prächtig, schließlich passte seine Philosophie hervorragend in die damalige Projektlandschaft von kleinen schnellen Teams in einer Welt mit sich rapide verändernden Anforderungen.
Mit dieser Ära ging teils auch der für innovative, sich selbst organisierende Projektteams nötige kulturelle Nährboden verloren.
Die Verbreitung von XP fand darin ihre organisatorischen Grenzen.
Und während der Name gerade in Programmiererkreisen große Aufmerksamkeit erzeugte, stieß er im Management übel auf.
Zudem war XP aus Sicht der Programmierer beschrieben, so dass die Änderungen in der Projektabwicklung aus Management- und Kundensicht nicht als Chancen, sondern lediglich als Risiken wahrgenommen wurden.
Dieses Bild will mit dem neuen XP korrigiert werden.
Denn mit seinem erweiterten Rollenmodell werden auch Nicht-Programmierer in das XP-Team eingebunden.
Lean Thinking
Auffällig ist, wie viele Anleihen aus dem Lean Manufacturing herausgearbeitet wurden.
Gerade die Parallelen zum Toyota Produktionssystem, der Just in Time Fertigungsstrategie des führenden japanischen Autobauers, können ein Weg sein, den XP-Ideen im Management zu einer höheren Akzeptanz zu verhelfen.
Über viele Jahre standen nur solche Fragen wie die Effizienz von Pair Programming, Testgetriebener Entwicklung oder eines Kunden vor Ort im Zentrum der Diskussion.
Dabei bekäme es der weiteren Akzeptanz besser, würde sich die Aufmerksamkeit in heutigen Zeiten des Kostendrucks mehr auf übergeordnete Themen wie Wertschöpfungsketten, Return on Investment, Zero Defects und Time to Market verlagern.
Denn durch die Einführung neuer Praktiken wie der Ursachenforschung zur Fehlerprävention sowie der Anwendung der Theory of Constraints zur Vermeidung von Flaschenhälsen gelingt es XP, die nötige, am japanischen Kaizen orientierte Philosophie der kontinuierlichen Prozessverbesserung zu etablieren.
Wie weit man jedoch mit dem extremen Programmieren gehen will, bleibt insbesondere nach Aufweichung der Praktiken jedermann selbst überlassen.
XP stellt in sich eh kein Ziel dar, sondern ist und bleibt ein Weg zur Verbesserung der Softwareentwicklung.
26.8.2001
Extreme Programming (XP) ist ein agiler Softwareentwicklungsprozess
für kleine Teams.
Der Prozess ermöglicht, langlebige Software zu erstellen und
während der Entwicklung auf vage und sich rasch ändernde
Anforderungen zu reagieren.
XP-Projekte schaffen ab Tag eins Geschäftswert für den
Kunden und lassen sich fortlaufend und außergewöhnlich
stark durch den Kunden steuern.
Im Kern beruht XP auf den Werten Kommunikation, Einfachheit,
Feedback, Mut, Lernen, Qualität und Respekt.
XP erfordert Disziplin und Prinzipientreue.
Die beschriebenen XP-Techniken sind jedoch wirklich nur die Startlinie.
Das Ziel ist es, den Entwicklungsprozess an die örtlichen
Begebenheiten anzupassen und fortlaufend zu verbessern.
Techniken für ein XP-Team
Ein XP-Team besteht aus zwei bis etwa zwölf Programmierern,
einem Kunden oder mehreren direkten Anprechpartnern auf Kundenseite
und dem Management.
Ferner erfordert der Prozess die Rollen des Trainers und Verfolgers.
Der Trainer bespricht mit dem Team die diszipliniert einzuhaltenden
Techniken und erinnert das Team, wenn es die selbstgewählten Regeln
verletzt.
Der Verfolger nimmt regelmässig den aktuellen Status und die
geleisteten Programmieraufwände auf, um so zuverlässige
Geschichtsdaten über das Projekt zu erhalten.
Zu beachten ist, daß der Kunde in der Regel weder den Geldgeber
noch den wirklichen Endanwender darstellt.
Offene Arbeitsumgebung
Das Team arbeitet zusammen in einem größeren Raum oder eng
aneinander grenzenden Räumen.
Typischerweise ist der "Kriegsraum" mit Wandtafeln und
unzähligen Flipcharts ausgestattet.
Die Arbeitstische stehen meist dicht beieinander im Kreis mit den
Monitoren nach außen gerichtet und sind so gestaltet, daß
zwei Programmierer zusammen bequem an einem Computer arbeiten können.
Kurze Iterationen
Die Entwicklung erfolgt in Perioden von ein bis drei Wochen.
Am Ende jeder Iteration steht ein funktionsfähiges, getestetes
System mit neuer, für den Kunden wertvoller Funktionalität.
Gemeinsame Sprache
Das Team entwickelt in seiner Arbeit ein gemeinsames Vokabular,
um über die Arbeitsweisen und das zu erstellende System diskutieren
zu können.
Die Kommunikation im Team erfolgt stets offen und ehrlich.
Retrospektiven
Jede Iteration endet damit, in einem Rückblick über die eigenen
Arbeitsweisen kritisch zu reflektieren und im Team zu diskutieren,
was gut lief und was in Zukunft anders angegangen werden muß.
Typischerweise werden aus den Dingen, die während dieser
Team-Reviews zur Oberfläche kommen, Regeln generiert,
vom Team akzeptiert, auf Poster geschrieben und im Projektraum zur
Erinnerung an die Wand geheftet.
Ein- oder zweimal jährlich macht das Team für zwei Tage einen
gemeinsamen Ausflug, um in einem Offsite-Meeting formal vor- und
zurückzublicken.
Tägliches Standup-Meeting
Der Tag beginnt mit einem Meeting, das im Stehen gehalten wird,
damit es kurz und lebendig bleibt.
Jedes Teammitglied berichtet reihum, an welcher Aufgabe er gestern
gearbeitet hat und was er heute machen wird.
Probleme werden genannt aber nicht gelöst.
Die meisten Teams treffen sich vor der Wandtafel ihrer Iterationsplanung.
Techniken für die Kunden
Benutzergeschichten
Die Kunden halten ihre Anforderungen in Form einfacher Geschichten auf
gewöhnlichen Karteikarten fest.
Jeder geschriebenen Story-Karte kommt das Versprechen nach,
den genauen Funktionsumfang zum rechten Zeitpunkt im Dialog mit den
Programmierern zu verfeinern und zu verhandeln.
Iterationsplanung
Jede Iteration beginnt mit einem Planungsmeeting, in dem das Kundenteam
seine Geschichten erzählt und mit dem Programmierteam diskutiert.
Die Programmierer schätzen den Aufwand grob ab, den sie zur
Entwicklung jeder einzelnen Geschichte benötigen werden.
Die Kunden wählen in Abhängigkeit der Aufwandsschätzungen
den Kartenumfang für die Iteration aus, der ihren
Geschäftsgegenwert maximieren würde.
Die Programmierer zerlegen die geplanten Geschichten am Flipchart in
technische Aufgaben, übernehmen Verantwortung für einzelne
Aufgaben und schätzen deren Aufwände vergleichend zu
früher erledigten Aufgaben.
Aufgrund der genaueren Schätzung der kleinen Aufgaben verpflichten
sich die Programmierer auf genau soviele Geschichten, wie sie in der
vorhergehenden Iteration entwickeln konnten.
Diese Planungsspiele schaffen eine sichere Umgebung, in welcher
geschäftliche und technische Verantwortung zuverlässig
voneinander getrennt werden.
Anforderungsdefinition im Dialog
Das für die anstehenden Programmieraufgaben nötige
Verständnis der Anforderungen wird fortlaufend in der
Konversation mit den Kunden geprüft und vertieft.
In kurzen Designsessions wird unter Umständen auf eine der
Wandtafeln ein wenig UML gemalt oder es werden Szenarien
mit Hilfe von CRC-Karten durchgespielt.
Während der gesamten Entwicklung dienen die Kunden als
direkte Ansprechpartner zur Bewältigung fachlicher Fragen.
Die verbleibende Zeit verbringen die Kunden mit dem Schreiben
und Ergründen neuer Benutzergeschichten und Akzeptanztests.
Akzeptanztests
Die Kunden spezifizieren während der Iteration funktionale
Abnahmekriterien.
Typischerweise entwickeln die Programmierer ein kleines Werkzeug,
um diese Tests zu kodieren und automatisch auszuführen.
Spätestens zum Ende der Iteration müssen die Tests
erfüllt sein, um die gewünschte Funktion des Systems zu sichern.
Kurze Releasezyklen
Nach ein bis drei Monaten wird das System an die wirklichen Endanwender
ausgeliefert, damit das Kundenteam wichtiges Feedback für die
Weiterentwicklung erhält.
Techniken für die Entwicklung
Programmieren in Paaren
Die Programmierer arbeiten stets zu zweit am Code und diskutieren
während der Entwicklung intensiv über Entwurfsalternativen.
Sie wechseln sich minütlich an der Tastatur ab und rotieren
stündlich ihre Programmierpartner.
Das Ergebnis ist eine höhere Codequalität, grössere
Produktivität und bessere Wissensverbreitung.
Gemeinsame Verantwortlichkeit
Der gesamte Code gehört dem Team.
Jedes Paar soll jede Möglichkeit zur Codeverbesserung jederzeit
wahrnehmen.
Das ist kein Recht sondern eine Pflicht.
Erst Testen
Gewöhnlich wird jede Zeile Code durch einen Testfall motiviert,
der zunächst fehlschlägt.
Die Unit Tests werden gesammelt, gepflegt und nach jedem Kompilieren
ausgeführt.
Design für heute
Jeder Testfall wird auf die einfachst denkbare Weise erfüllt.
Es wird keine unnötig komplexe Funktionalität programmiert,
die momentan nicht gefordert ist.
Refactoring
Das Design des Systems wird fortlaufend in kleinen, funktionserhaltenden
Schritten verbessert.
Finden zwei Programmierer Codeteile, die schwer verständlich sind oder
unnötig kompliziert erscheinen, verbessern und vereinfachen sie den Code.
Sie tun dies in disziplinierter Weise und führen nach jedem Schritt
die Unit Tests aus, um keine bestehende Funktion zu zerstören.
Fortlaufende Integration
Das System wird mehrmals täglich durch einen automatisierten
Build-Prozess neu gebaut.
Der entwickelte Code wird in kleinen Inkrementen und spätestens
am Ende des Tages in die Versionsverwaltung eingecheckt und ins
bestehende System integriert.
Die Unit Tests müssen zur erfolgreichen Integration zu 100% laufen.
Techniken für das Management
Akzeptierte Verantwortung
Das Management schreibt einem XP-Team niemals vor, was es zu tun hat.
Stattdessen zeigt der Manager lediglich Probleme auf und läßt
die Kunden und Programmierer selbst entscheiden, was zu tun gilt.
Dies ist eine große, neue Herausforderung für das Management.
Information durch Metriken
Eine der Hauptaufgaben des Managements ist es, dem Team den Spiegel
vorzuhalten und zu zeigen, wo es steht.
Dazu gehört unter anderem das Erstellen einfacher Metriken,
die den Fortschritt des Teams oder zu lösende Probleme aufzeigen.
Es gehört auch dazu, den Teammitgliedern regelmässig in die
Augen zu schauen und herauszufinden, wo Hilfe von Nöten ist.
Ausdauerndes Tempo
Softwareprojekte gleichen mehr einem Marathon als einem Sprint.
Viele Teams werden immer langsamer bei dem Versuch, schneller zu
entwickeln.
Überstunden sind keine Lösung für zuviel Arbeit.
Wenn Refactorings und Akzeptanztests aufgeschoben werden, muß
der Manager dem Team stärker den Rücken freihalten.
Wenn Teammitglieder müde und zerschlagen sind, muß
der Manager sie nach Hause schicken.
Links
Bücher
Mailinglisten
User's Groups
19.2.2001
Ein erster Einblick
Wie sieht ein Tag mit Extreme Programming aus?
Nun, Sie werden wie gewohnt programmieren.
Obwohl, nicht ganz.
Sie programmieren mit einem Partner.
Sie arbeiten zu zweit an einer kleinen überschaubaren Aufgabe.
Die Zerlegung in Aufgaben haben Sie kurz zuvor im Team in einem kurzen
Design-Meeting mit dem Kunden diskutiert und geplant.
Sie haben die Verantwortlichkeit für eine Reihe von Aufgaben akzeptiert
und suchen sich für deren kurze Dauer jeweils einen Programmierpartner.
Bevor Sie gemeinsam zu programmieren beginnen, analysieren Sie und Ihr Partner
zunächst, was Ihr Auftraggeber überhaupt an Anforderungen stellt.
Dazu möchten Sie unter Umständen direkt mit Ihrem Kunden sprechen.
Er arbeitet wenige Meter von Ihnen beiden entfernt im gleichen Büro,
damit Fragen des Entwicklungsteams unmittelbar diskutiert werden können.
Jetzt wissen Sie beide, was verlangt wird, und Sie können endlich
losprogrammieren.
Einen Augenblick.
Bevor Sie losprogrammieren, überlegen Sie und Ihr Partner sich zunächst
ein Design dafür, wie die Anforderungen überhaupt umgesetzt werden sollen.
Dazu schreiben Sie eine Reihe von Testfällen.
Anschliessend schreiben Sie den Code, der diese Tests erfüllt.
Dabei streben Sie stets die einfachste Lösung an.
Testfall für Testfall erhalten Sie grünes Licht und gehen weiter.
Die Aufgabe gilt dann als erledigt, wenn Ihnen beiden keine weiteren Tests
mehr einfallen, die sich für die aktuellen Anforderungen sinnvoll schreiben
liessen.
Wenn alle Ihre Tests erfüllt sind, verlangt XP von Ihnen, den geschriebenen
Code noch möglichst zu vereinfachen und sein Design zu verbessern.
Der Code darf unter anderem keine duplizierte Logik enthalten und muß jede
Intention ausdrücken, die für das Verständnis des Programms notwendig
erscheint.
Nachdem Sie den Code in Form gebracht haben, lassen Sie Ihre Arbeit durch
die Suite aller im Team gesammelten Tests kontrollieren und integrieren
schließlich Ihren geschriebenen Code mit den Änderungen Ihrer Teamkollegen.
Anschliessend besorgen Sie sich zunächst einmal frischen Kaffee und helfen
eventuell direkt Ihrem Partner bei seiner nächsten Programmieraufgabe.
Ein XP-Tag geht schnell vorüber, da Sie den ganzen Tag lang intensiv
mit Ihren Kollegen programmiert haben.
Das bedeutet nicht etwa, daß Sie Ihrem Partner bei der Arbeit über die
Schulter schauen.
Im Gegenteil.
Im Paar zu programmieren bedeutet aufmerksam in die Programmierepisode
involviert zu sein.
Sie unterhalten sich über den Code, den sie gemeinsam schreiben.
Regelmässig übergeben Sie Ihrem Partner die Tastatur und lassen ihn
"fahren".
Am Ende eines solchen Tages sind Sie erschöpft und, glauben Sie mir,
Sie gehen pünktlich nach Hause, weil Sie acht Stunden lang fokussiert
gearbeitet haben und die geschriebenen Tests Ihnen Vertrauen in die
geleistete Arbeit geben.
Zugegeben, der Name "Extreme Programming" läßt einen extrem
einseitigen Ansatz der Softwareentwicklung vermuten.
Auf den zweiten Blick jedoch widmet sich XP sehr viel intensiver
der Analyse, dem Design und dem Test als schwergewichtige Methoden.
XP bringt uns zurück zu den Wurzeln des Handwerks guter Programmierung
und der Fragestellung, was wirklich zählt, wenn wir hochqualitative Software
erstellen wollen.
Ich möchte Sie dazu einladen, das Handwerk von XP und das Lebensgefühl eines
leichtgewichtigen Prozesses kennenzulernen.
Begleiten Sie mich auf den folgenden Seiten durch ein XP-Projekt und schauen
Sie dem Team bei der täglichen Arbeit über die Schulter und in die Karten.
Programmieren in Paaren
Die Regel lautet: Wer um Hilfe bittet, dem wird Hilfe geboten.
Tatsächlich wird keine Zeile Produktionscode geschrieben, ohne daß zwei Paar
Augen auf den Bildschirm gerichtet sind.
Das bedeutet, Sie programmieren zu zweit an einem Rechnern mit einer Tastatur
und einer Maus.
Sie sitzen nebeneinander, führen ein intensives Gespräch über den
entstehenden Code und wechseln sich regelmässig an der Tastatur ab.
Sie dürfen dabei sogar Spaß haben, denn Programmieren soll Spaß bringen.
Sie wechseln häufiger Ihre Programmierpartner und am Ende der Woche haben
Sie idealerweise mal mit jedem Ihrer Kollegen zusammengearbeitet, damit sich
das aufgebaute Wissen über das gesamte Team verbreitet.
Felix und Ulrich, Dienstag, 1.Iteration, 11.03 Uhr
Ulrich: Was ist unsere Aufgabe?
Felix: Wir müssen die Miete für ausgeliehene DVDs berechnen.
Ulrich: Wie berechnen wir das?
Felix: Der Preis ist abhängig davon, wie lange eine DVD ausgeliehen wird.
Ulrich: Und wie?
Felix: Laß mich mal sehen... Auf unserer Karte steht, reguläre Filme kosten für zwei Tage
2 Euro. Ab dem dritten Ausleihtag dann 1.5 Euro pro Tag.
Ulrich: Okay, wie machen wir das also?
Felix: Mmm, ich schlage vor, wir merken uns zunächst mal, welche Filme ein
Kunde ausleiht und berechnen später die Miete anhand der Ausleihtage.
Ulrich: Warum berechnen wir die Kosten nicht auf der Stelle?
Felix: Das ist später vielleicht notwendig, aber momentan ist das keine
Anforderung.
Ulrich: Schön, wie soll unsere erste Klasse heissen?
Felix: Spannende Frage... Die Verantwortlichkeiten klingen fast danach, als
würde sich die Klasse selbst Customer nennen wollen.
Ulrich: Fangen wir damit mal an.
Felix: Stop mal! Laß uns gleich einen Test dafür schreiben...
Ulrich: Gut, dazu muß unsere Testklasse von TestCase aus dem
Test-Framework ableiten.
Felix: Und dann bekommt sie noch einen Konstruktor für den Namen des
Testfalls.
public class CustomerTest extends junit.framework.TestCase {
public CustomerTest(String name) {
super(name);
}
}
Testgetriebenes Programmieren
Die anzustrebende Geisteshaltung muß sein, daß eine Funktion solange nicht
existiert, bis sie einen automatisierten Test besitzt.
Tatsächlich entsteht kein Produktionscode, bevor es nicht einen
entsprechenden Testfall gibt, der fehlschlägt.
Das bedeutet, Sie schreiben einen Test noch bevor Sie den Code schreiben,
der diesen Test erfüllt.
Sie erstellen inkrementell eine umfassende Suite von Unit Tests, die das gesamte Programm
in isolierten Einheiten auf die erwartete Funktion hin überprüft.
Sie verwenden ein Test-Framework, das Ihnen dabei hilft, automatische
Tests zu schreiben und auszuführen.
Sie sammeln und pflegen diese Tests, damit Sie nach jeder Änderung
sicherstellen können, daß die Testsuite zu 100% läuft.
Ulrich: Was ist der erste Testfall?
Felix: Das einfachste wäre, wir fangen mit dem Ausleihen eines Films an.
Ulrich: Und wie?
Felix: Es ist so, daß wir für jede Methode, die funktionieren soll,
Zusicherungen schreiben wollen, um die Funktion abzuprüfen.
Ulrich: Dafür ist die assertTrue Methode gedacht, die wir aus
TestCase erben.
Felix: Genau. Als Parameter erwartet sie eine Bedingung, die true
ergeben muß, damit der Testfall als erfüllt gilt. Den Rest erledigt das
Framework.
Ulrich: Und wohin schreiben wir nun den Testcode?
Felix: Am besten schreiben wir dafür eine Testfallmethode testRentingOneMovie, die
dann die Mietkosten für den Film testet. Das Framework findet automatisch
alle Methoden, die mit test beginnen, und führt sie aus.
Ulrich: Gut, schreiben wir mal auf, was wir bis jetzt wissen. Wir benötigen
zunächst mal ein Customer Exemplar. Und dann muß ich so tun, als
gäbe es einfach alle Methoden schon, die ich mir wünsche.
Felix: Richtig. Wir leihen eine DVD für einen Tag aus und es soll 2 Euro
kosten.
Ulrich: Das ist einfach.
public class CustomerTest...
public void testRentingOneMovie() {
Customer customer = new Customer();
customer.rentMovie(1);
assertTrue(customer.getTotalCharge() == 2);
}
}
Möglichst einfaches Design
Die Designstrategie sieht vor, mit einem schlichten Design zu starten und
dieses fortlaufend zu verbessern.
Tatsächlich werden Designelemente, die komplizierter sind, als momentan
unbedingt notwendig wäre, aufgeschoben, selbst wenn nur für wenige Minuten.
Das bedeutet, Sie wählen von vielen verschiedenen Lösungswegen denjenigen,
der am einfachsten erscheint, um einen Testfall zu erfüllen.
Sie programmieren nur, was Sie jetzt tatsächlich benötigen, nicht, was Sie
später vielleicht benötigen.
Sie gehen sogar soweit, daß Sie unnötige Flexibilität wieder aus dem Code
entfernen.
Sie treten den Beweis dafür an, daß die aktuelle Lösung zu einfach ist,
indem Sie einen Testfall schreiben, der ein komplexeres Design rechtfertigt.
Ulrich: Also gut. Du willst, daß ich nur den Test zum Laufen bringe und
alles andere für einen Moment vergesse.
Felix: Ganz genau. Was würdest Du tun, wenn Du nur diesen einen Test
implementieren müsstest?
Ulrich: Hah, auch das ist einfach.
public class Customer {
public void rentMovie(int daysRented) {
}
public int getTotalCharge() {
return 2;
}
}
Felix: Wie extrem! Aber gut...
Ein wenig Testen, ein wenig Programmieren...
Das Zusammenspiel von testgetriebenem Programmieren und einfachem Design
ergibt den Zyklus des minutenweisen Programmierens.
Tatsächlich wird nie länger als zehn Minuten programmiert, ohne die
Feedbackschleife unmittelbar durch konkrete Tests zu schliessen.
Das bedeutet, Sie schreiben neuen Code in so winzigen Schritten, daß Ihr
Code gerade mal den aktuellen Testfall erfüllt.
Sie testen ein wenig, Sie programmieren ein wenig.
Dann testen Sie wieder und programmieren...
Minute für Minute feiern Sie einen kleinen Erfolg.
Sie schreiben keine ganze Klasse in einem Rutsch.
Vielmehr schreiben Sie nur ein paar Zeilen Code, maximal eine Methode auf
einmal.
Ulrich: Als nächstes möchte ich zwei und drei ausgeliehene DVDs testen.
Felix: Immer langsam... Schreib erst mal den Test für zwei Filme.
Der Zweite wird für zwei Tage entliehen. Die Summe soll 4 Euro betragen.
Laß uns dazu die assertEquals Methode benutzen.
Als Parameter erhält sie den erwarteten Wert und das tatsächliche Resultat.
public class CustomerTest...
public void testRentingTwoMovies() {
Customer customer = new Customer();
customer.rentMovie(1);
customer.rentMovie(2);
assertEquals(4, customer.getTotalCharge());
}
}
Ulrich: Okay, dieser Test wird nicht laufen.
Felix: Woher weisst Du das? Schau nach, Du weisst nie!
Ulrich: Sagen wir einfach, ich bin mir ziemlich sicher.
Felix: Gut, wenn Du es also weisst und nehmen wir an, der Test zeigt grün,
würde das demnach bedeuten, daß entweder unser Test falsch ist oder aber der
Code Dinge tut, die er nicht machen darf, richtig? Mach den Test!
Ulrich: Also gut... Der Test zeigt rot.
Felix: Diesmal kommst Du auch nicht mehr so einfach davon...
public class Customer {
private int totalCharge = 0;
public void rentMovie(int daysRented) {
totalCharge += 2;
}
public int getTotalCharge() {
return totalCharge;
}
}
Evolutionäres Design
Organisches Wachstum scheint eine gute Strategie zu sein, um auf
Veränderung und Ungewissheit reagieren zu können.
Tatsächlich werden Anforderungsänderungen als Chance und nicht
als Problem betrachtet.
Das bedeutet, Sie verhalten sich im Design so, als wüssten Sie wirklich
nicht, was die nächsten Anforderungen sein würden.
Sie entwerfen stets die einfachste Lösung und bringen Ihren Code
anschliessend in die einfachste Form.
Sie vertrauen auf die Tatsache, daß sauber strukturierter Code in jede
Richtung mitziehen kann und daß der Code, den Sie gestern geschrieben haben,
Sie heute und morgen dabei unterstützen wird, weiterhin Code zu schreiben,
und Sie nicht zunehmend daran hindert.
Ulrich: Was ist der nächste Testfall?
Felix: Ein dritter Film, der drei Tage entliehen wird.
Ulrich: Wieviel kostet der Film, wenn er erst nach drei Tagen zurückgegeben wird?
Felix: Jeder weitere Tag kommt auf 1.5 Euro.
Ulrich: Also 3.5 Euro am Tag drei. Macht zusammen 7.5 Euro. Ausserdem können wir Fließkommazahlen nicht mit unendlicher Genauigkeit vergleichen.
public class CustomerTest...
public void testRentingThreeMovies() {
Customer customer = new Customer();
customer.rentMovie(1);
customer.rentMovie(2);
customer.rentMovie(3);
assertEquals(7.5, customer.getTotalCharge(), 1e-3);
}
}
Felix: Ab jetzt müssen wir 1.5 Euro draufschlagen.
Ulrich: Das bedeutet auch, daß totalCharge ab sofort Fließkommazahl sein
möchte.
public class Customer {
private double totalCharge = 0;
public void rentMovie(int daysRented) {
totalCharge += 2;
if (daysRented > 2) {
totalCharge += 1.5;
}
}
public double getTotalCharge() {
return totalCharge;
}
}
Felix: Nun meckert aber der Compiler rum... Wir müssen wohl auch unseren vorherigen Testfall zum Vergleich von Fließkommazahlen bringen.
public class CustomerTest...
public void testRentingTwoMovies() {
Customer customer = new Customer();
customer.rentMovie(1);
customer.rentMovie(2);
assertEquals(4, customer.getTotalCharge(), 1e-3);
}
}
Natürlicher Abschluß einer Programmierepisode
Bewußt aufhören zu können ist einer der stärksten Programmierzüge.
Tatsächlich ist eine Aufgabe fertig, wenn alle Randbedingungen getestet sind,
die dazu führen können, daß etwas schief geht.
Das bedeutet, Sie schreiben nicht für jede Methode einen Test, sondern nur
für solche, die unter Umständen fehlschlagen könnten.
Sie halten Ihr Wissen über den Code fest, während Sie Tests dafür
schreiben.
Sie wissen, daß Sie erreicht haben, was Sie sich vorgenommen hatten, wenn
alle Ihre Tests erfüllt sind.
Zum Abschluß sei es Ihnen gegönnt, über Ihre Programmierepisode
zu reflektieren.
Sie wollen ja schließlich jeden Tag etwas dazulernen.
Ulrich: Ein Film, der vier Tage entliehen wird?
Felix: Kostet 5 Euro und macht dann insgesamt 12.5 Euro.
public class CustomerTest...
public void testRentingFourMovies() {
Customer customer = new Customer();
customer.rentMovie(1);
customer.rentMovie(2);
customer.rentMovie(3);
customer.rentMovie(4);
assertEquals(12.5, customer.getTotalCharge(), 1e-3);
}
}
Felix: Laß mich mal tippen!
Ulrich: Okay!
public class Customer...
public void rentMovie(int daysRented) {
totalCharge += 2;
if (daysRented > 2) {
totalCharge += (daysRented - 2) * 1.5;
}
}
}
Felix: So, das hätten wir. Haben wir irgendwelche Tests vergessen?
Ulrich: Müsste mit dem Teufel zugehen...
Refactoring
Gutes Design ist nie einfach und niemand bekommt die Dinge im ersten Versuch
in den Griff.
Tatsächlich entsteht ein Design durch schrittweises Wachstum und ständige
Überarbeitung.
Das bedeutet, daß Sie alle Erfahrungen in das Design zurückfliessen lassen
und das Design verbessern, nachdem der Code geschrieben wurde.
Sie refaktorisieren, um Ihren Code so einfach und so verständlich wie
möglich zu machen und jede Art von Redundanz zu beseitigen.
Ulrich: Wenn ich mir unseren Code ansehe, frage ich mich, was die vielen
Zahlen bedeuten. Wir sollten denen Namen geben!
Felix: Vorschläge?
public class Customer...
static final double BASE_PRICE = 2; // Euro
static final double PRICE_PER_DAY = 1.5; // Euro
static final int DAYS_DISCOUNTED = 2;
}
Ulrich: Eigentlich finde ich die Änderung ja zu klein, um nach jedem
Schritt zu testen...
Felix: Du hast Mut, aber wir haben ja noch die Tests...
public class Customer...
public void rentMovie(int daysRented) {
totalCharge += BASE_PRICE;
if (daysRented > DAYS_DISCOUNTED) {
totalCharge += (daysRented - DAYS_DISCOUNTED) * PRICE_PER_DAY;
}
}
}
Ulrich: Irgendwie passen die Konstantennamen nun aber doch nicht mehr zu der
Klasse.
Felix: Stimmt, das hat jetzt schon sehr viel mit der eigentlichen
Preisberechnung für den Film zu tun.
Ulrich: Ziehen wir eine neue Klasse Movie raus, um dem Ausdruck zu
verleihen!?
Felix: Einverstanden, aber erst die Tests...
public class MovieTest extends junit.framework.TestCase {
public MovieTest(String name) {
super(name);
}
public void testGetCharge() {
assertEquals(2.0, Movie.getCharge(1), 1e-3);
assertEquals(2.0, Movie.getCharge(2), 1e-3);
assertEquals(3.5, Movie.getCharge(3), 1e-3);
assertEquals(5.0, Movie.getCharge(4), 1e-3);
}
}
Felix: Die Preisberechnung verschieben wir einfach auf diese Klasse...
public class Movie {
static final double BASE_PRICE = 2; // Euro
static final double PRICE_PER_DAY = 1.5; // Euro
static final int DAYS_DISCOUNTED = 2;
public static double getCharge(int daysRented) {
double result = BASE_PRICE;
if (daysRented > DAYS_DISCOUNTED) {
result += (daysRented - DAYS_DISCOUNTED) * PRICE_PER_DAY;
}
return result;
}
}
Felix: Unser Customer wird dadurch wieder ganz schlank...
public class Customer...
public void rentMovie(int daysRented) {
totalCharge += Movie.getCharge(daysRented);
}
}
Fortlaufende Integration
Neuer Code wird schnellstmöglich in die neueste Version integriert.
Tatsächlich wird mehrmals täglich ein getesteter Build des gesamten
Programms erstellt.
Das bedeutet, daß Sie am Ende jeder Programmierepisode und wenigstens einmal
am Tag Ihren geschriebenen Code in das Programm integrieren und versionieren.
Sie laden Ihre Änderungen auf einen dedizierten Integrationsrechner,
integrieren Ihren Code und beseitigen entstehende Konflikte.
Sie führen die Tests aus und geben Ihren Code frei, sobald alle Tests
erfolgreich ausgeführt werden.
Die gesamte Integrationsprozedur dauert gerade so lange, daß Sie sich eine
frische Tasse Kaffee kochen und sie austrinken können.
Felix: Laß uns unseren Code integrieren und Mittag machen!
Ulrich: Milchkaffee oder Chinese?
Nächster Artikel in dieser Serie:
Unit Tests mit JUnit
Danksagungen
Leah Striker,
Michael Schürig,
Meike Budweg,
Tammo Freese,
Ulrike Jürgens,
Hans Wegener,
Marko Schulz,
Antonín Andert,
Manfred Lange
und Julian Mack
haben das Beispiel entstehen sehen und nützliche
Verbesserungsvorschläge gemacht.
Der Ehrentitel eines Meisterrezensenten sei an Rolf F. Katzenberger verliehen.
30.11.2006
Nachdem ich am vergangenen Freitag auf dem XPday schon darauf angesprochen wurde und auch Johannes und ich heute noch mal auf das Thema kamen, dachte ich mir, ich poste einfach schnell mehr dazu … vielleicht interessiert's ja noch wen.
Die kürzesten XP-Projekte der Welt
Einen neuen Prozess zu erlernen und gleichzeitig seine Arbeit zu machen, geht häufig nicht so gut zusammen. Zum Lernen gehört Experimentieren und zum Experiment gehört das erlaubte (und irgendwo auch explizit gewünschte) Fehler-machen-dürfen. Ohne das, kein Lerneffekt.
Im XP haben wir schon recht früh auf Simulation und Prozessminiatur gesetzt. Ganz nach dem XP-Prinzip der kleinen Anfangsinvestition kann man so XP spielerisch erfahrbar machen. Um ein ganzes Projekt in einer guten Stunde zu simulieren, gibt es zwei Spielarten. Beide machen sie einen Heidenspaß, fokussieren jedoch auf unterschiedliche Aspekte:
Extreme Hour
Die Extreme Hour (von Peter Merel) dreht 6-7 Iterationen à 10 Minuten. Das Team besteht aus Entwicklern, Kunden, QA, Tracker und Coach. Ihre Aufgabe ist es, z. B. eine bessere Mausefalle zu entwickeln oder einen modernen Haushaltsroboter. Die Arbeitsergebnisse werden typischerweise in Story-Form skizziert, programmiert wird nicht.
Vorteile
- explizite Teamrollen und -verantwortlichkeiten
- realistische (wenn auch extreme) Timebox
- setzt viel Kommunikation voraus
- produziert natürliche Integrationsaufwände
Nachteile
- Abnahmekriterien nur relativ vage (man muss sich einigen :-)
- Iterationen neigen in der XH dazu, den Fokus auf bestimmte Aktivitäten zu lenken, dadurch ein wenig zu wasserfallartig
- wenig bis gar kein vergleichendes Aufwandsschätzen möglich
XP-Game
Im XP-Spiel
(von Vera Peeters und Pascal Van Cauwenberghe) sind die Iterationen noch kürzer: exakt 120 Sekunden. Das Team teilt sich im wesentlichen auf Entwickler und Kunden auf, plus Tracker (mit Stoppuhr). Zu erledigen sind echte, physikalische Aufgaben, wie Kartenhäuser bauen, Luftballons aufpusten oder Rätsel lösen.
Vorteile
- Aufgaben haben harte Abnahmekriterien
- trainiert Aufwandsschätzung über mehrere Iterationen
Nachteile
- weniger Teamarbeit, keine Integration, wenig Kommunikation
- Iterationen fast zu spielerisch (Aufgaben werden einzeln gestoppt)
- Aufgaben relativ isoliert voneinander
XP-Programmierpraktiken vermitteln sie beide nicht. Die Extreme Hour konzentriert sich mehr auf Teamrollen, Kommunikation und Integration. Das XP-Game veranschaulicht dagegen besser den Planungsprozess, das vergleichende Schätzen und das "Wetter von gestern". Je nach dem, was im Mittelpunkt stehen soll, wähle man die eine oder andere Simulation. Für alle, die's selbst ausprobieren wollen, viel Spaß:
Materialien
20.11.2006
Einen weiteren kleinen Schatz möchte ich ebenfalls nicht für mich behalten. Im Frühjahr 2001 zettelten Tammo und ich in unseren ersten XP-Vorträgen die große Revolution an. Die ersonnenen Aufstände blieben jedoch aus. Bis heute. Wir waren jünger und naiver. Damals:
XP, der Aufstand der Programmierer?
Wir wollen Qualität abliefern.
Wir wollen wissen, was der Kunde in welcher Reihenfolge entwickelt haben möchte.
Wir wollen Unterstützung von Kollegen und Kunden bekommen, wenn wir sie brauchen.
Wir wollen unsere eigenen Abschätzungen machen und sie aktualisieren dürfen.
Wir wollen Verantwortlichkeit übernehmen und sie nicht zugewiesen bekommen.
XP, der Aufstand der Kunden?
Kunden wollen wissen, was bis wann und zu welchen Kosten erreicht werden kann.
Kunden wollen aus jedem Personentag den maximalen Wert ziehen.
Kunden wollen den Projektfortschritt sehen.
Kunden wollen ihre Meinung ändern können.
Kunden wollen Planänderungen so früh wie möglich erfahren; Kunden sollten jederzeit aussteigen können.
Kunden wollen nicht belogen werden.
20.11.2006
Vor ein paar Tagen habe ich ein paar alte Vortragsfolien wieder entdeckt … die ich überraschend gut finde. Für eine Konferenz im Herbst 2002 in Helsinki hatte ich mich von Dee Hock (Gründer von VISA) anstecken lassen und XP in Form einfacher, generativer Regeln vorgestellt. Hock hat die Chaostheorie auf Organisationen angewandt; heraus kamen chaordische
Organisationen (Wortkreuzung aus Chaos und Ordnung) und ein tolles Buch: Birth of the Chaordic Age. Seine Schlussfolgerung war:
Einfache, klare Ziele und Prinzipien führen zu komplexem, intelligenten Verhalten. Komplexe Regeln und Vorschriften führen zu einfachem, dummen Verhalten.
Daraus motiviert habe ich meine damaligen XP-Regeln aufgestellt. Einige klingen aus heutiger Sicht schon gar nicht mehr extrem. Und zu viele sinds. Wobei ich allerdings auch nicht wüsste, was ich weglassen sollte:
program in pairs
motivate each change of program behavior with an automated unit test
refactor the code into its simplest form
integrate your code as often as necessary
check every requirement with an automated acceptance test
ship a working system with new valuable functionality at least every 2 weeks
release the system at least every few weeks to users outside the team
customer is always available to answer questions
whole team works together in an open space area
have a standup meeting every day at the same time
align authority and responsibility
always work on the most important business problem
plan a little bit every day, for the iteration every 2 weeks, for the release every 3 months
design for today
periodically reflect on your process and tune it
always have enough time to complete your job
27.1.2005
Diese Woche habe ich die OOP-Konferenz in München besucht.
Mein Vortrag dort drehte sich um die Fragen:
- Was hat Extreme Programming (XP) über die bekannten Programmierpraktiken hinaus für Planung und Management von Softwareprojekten zu bieten?
- Wie hat sich XP aus den Erfahrungen der vergangenen fünf Jahre weiterentwickelt?
- Was muss man beachten, damit sich Agilität nicht nur im Entwicklungsbereich, sondern im Geschäft selbst niederschlägt?
- Wie funktioniert XP in größeren Teams und Organisationen?
Darüber hinaus habe ich diskutiert, wie wir Softwareentwicklung als Wertschöpfungsprozess verstehen sollten, was die zweite Auflage von XP an Neuerungen zu bieten hat und was Lean Development bedeutet.
Nachfolgend präsentiere ich einen Abriss der nicht-technischen Praktiken von Industrial XP: Assessments, Business Stories, Charters und mehr.
Was ist Industrial XP?
-
XP für große Teams und Organisationen
- verfeinert die vorhandenen Praktiken
- erweitert das Repertoire um neue Praktiken für alle Projektbeteiligten
-
macht implizites XP-Wissen explizit
- betont immer die Aspekte, die in der Praxis am sträflichsten vernachlässigt werden
Werte und Praktiken

© Industrial Logic
Readiness Assessment
- Ist die Project Community und Organisation bereit zur Veränderung?
-
Kann die Project Community mit XP erfolgreich sein?
- initiale Bewertung
- ständige Neubewertung
Assessments
- offene Arbeitsumgebung?
- Pairingmöglichkeiten? Möbel? Kernzeit?
- Domänenexperten verfügbar?
- untestbarer Legacy Code? Refactoringtools?
- Codeeigentümer?
- Datenbank zugreifbar? Schema änderbar?
Risk Management
- Welche Projektrisiken bestehen?
-
Was können wir gegen sie unternehmen?
- Top 10 technische Risiken
- Top 10 organisatorische Risiken
Projektrisiken

- Sind diese Risiken zu hoch, um das Projekt weiterzuführen? Falls nein, wie lassen sich diese Risiken mindern?
- Diese Risiken fortlaufend nach Auslösern überwachen, die sie zum größeren Risiko werden lassen.
- Nur angehen, wenn nichts besseres zu tun.
Project Chartering
- Lohnt sich die Projektidee überhaupt?
- Wie wird die Vision/Mission der Organisation durch das Projekt unterstützt?
- Woran erkennen wir einen Projekterfolg?
- Wer zählt zur Project Community?
Charter
- Vision und Mission-Statement
- Project Community
- Werte
- verpflichtete Resourcen
- Erfolgsmaßstäbe
- Kontextdiagramm
Project Community
- Wer hat Einfluss auf den Projekterfolg?
-
Wen betrifft das Projekt?
- häufig ein wesentlich größerer Personenkreis als zunächst angenommen
Werte
- Welche Werte teilt die Project Community?
-
Sind die Werte mit den XP-Praktiken zu vereinbaren?
- wenn ja, lassen wir uns in unserem Handeln durch die Werte leiten
- wenn nein, müssen wir eine andere (agile) Methode in Betracht ziehen
Test-Driven Management
-
Welche Erwartungen an das Projekt bestehen aus Managementsicht?
- interne Tests: auf Ebene der IT-Abteilung
- externe Tests: auf Organisationsebene
Business Stories
Apple's Managementtest für den iTunes Music Store:
"Our new service will register at least 1 million song downloads during its first month in production."
SMART: Specific, Measurable, Achievable, Relevant, Time-Based
Retrospectives
- Was lief gut, was nicht vergessen werden sollte?
- Was haben wir gelernt?
- Was sollten wir nächstes Mal anders machen?
- Was stört uns immer noch?
- Was müssen wir noch näher diskutieren?
Iterationsretrospektiven

Links
27.6.2006
Zwei Events in diesem Herbst unter dem Motto Architecture of Participation
:
Endlich ... das erste deutsche Barcamp:
Berlin
(30.9.-1.10.2006)
Ebenfalls vormerken: XPdays
Hamburg (24.11.2006)
25.2.2001
Die Autoren von Scrum, XP, DSDM, ASD und Crystal sowie einige vergleichbar
erfahrene Leute einigten sich auf das Manifest für agile
Softwareentwicklung:
Wir zeigen bessere Wege zur Softwareentwicklung auf, indem wir Software
entwickeln und anderen dabei helfen. Wir bevorzugen:
-
Menschen und Zusammenarbeit vor Prozessen und Werkzeugen
-
Funktionierende Software vor umfassender Dokumentation
-
Zusammenarbeit mit dem Kunden vor vertraglicher Verhandlung
-
Reaktion auf Veränderung vor Einhaltung eines Plans
Das heißt, während die Punkte auf der Rechten wertvoll sind,
wertschätzen wir die Punkte auf der Linken mehr.
Weitere Links
8.1.2001
Agile Softwareentwicklungsprozesse sind zweifellos en vogue. Sie
unternehmen den Versuch, die Anzahl der im Prozess zu erstellenden
Artefakte weitestgehend zu reduzieren. Das bedeutet, daß sich das
Gewicht eines jeden Artefakts rechtfertigen muß und auf die Erstellung
und Pflege von Nebenprodukten jenseits vom Programmcode verzichtet wird, wenn
das Risiko dafür gering genug ist.
Momentan dominiert
Extreme Programming
die Diskussion um die leichtgewichtigen Methoden. Vielleicht nicht ohne
Grund, denn XP kommt mit seinen zwölf Techniken vergleichsweise konkret
daher. Andererseits erfordert der Prozess jedoch hohe Disziplin im Team.
Weitere Vertreter
der leichtgewichtigen Familie für
Agile Softwareentwicklung
sind z.B.:
Vergessen Sie bitte nicht:
- Softwareentwicklung soll Spaß machen. Tut sie das nicht, ist der
Prozess defekt.
- Jedes Projekt und jedes Team ist einzigartig und benötigt damit
seinen eigenen maßgeschneiderten Prozess.
- Der Prozess gehört dem Team. Jedes Team entscheidet selbst
(akzeptiert), welche Regeln es befolgen will (und welche nicht). Mit einem
aufgezwungenen Prozess kommt es oft zur Schieflage, weil Autorität
und Verantwortlichkeit für den Prozess nicht einer Hand liegen.
- Ihr Entwicklungsprozess ist ein wanderndes Ziel. Sie sollten ihn
ständig verbessern und ihn an Ihre örtlichen Begegebenheiten
anpassen.
- Es muß nicht unbedingt XP sein. Leichtgewichtigkeit an sich kann
schon ein wertvolles Ziel sein.
Weitere Links