Extreme programming

Extreme programming (ook wel XP genoemd) is een vorm van agile-softwareontwikkeling, een softwareontwikkelingsmethodiek.

Geschiedenis

De belangrijkste grondleggers van extreme programming zijn Kent Beck, Ken Auer, Ward Cunningham, Martin Fowler en Ron Jeffries. Zij ontwikkelden XP tijdens het Chrysler Comprehensive Compensation System (C3) project in 1996. Zij omschrijven XP als "a humanistic discipline of software development, based on principles of simplicity, communication, feedback, and courage" (vrij vertaald: "een humanistische discipline van software-ontwikkeling, gebaseerd op de beginselen van eenvoud, communicatie, feedback, en moed"). XP is een methodiek die vooral geschikt is voor projecten waarbij de exacte applicatie-eisen niet bij voorbaat vastliggen.

Ontwikkelprincipes, best practices

Extreme programming dankt zijn naam aan het feit dat een aantal beproefde ontwikkelprincipes (zogenaamde best practices) tot in het extreme wordt doorgevoerd. De optimale kracht van XP komt voort uit het in samenhang toepassen van twaalf best practices van software ontwikkeling. De best practices zijn gegroepeerd in vier groepen.[1] (feedback, continu proces, gedeelde kennis en het welzijn van de ontwikkelaars).

Feedback

Pair programming

XP stelt dat uiteindelijk alles om code draait bij het maken van software. Als het goed is dat ontwikkelaars code bij elkaar reviewen, doe het dan voortdurend: ontwikkel alle software in koppels. Met andere woorden, twee mensen achter één computer; pair programming genoemd. Dit is meteen ook een van de meest extreme en controversiële aspecten van XP, omdat men denkt dat het dan langzamer gaat. Maar onderzoek heeft aangetoond dat peer-review en code-inspectie de krachtigste wapens zijn tegen bugs, veel krachtiger zelfs dan systematisch testen. Toch worden deze technieken nog maar mondjesmaat toegepast en roepen ze vaak grote weerstand op bij de programmeurs zelf, en bij managers die bang zijn voor een stijgend aantal arbeidsuren.

Door af te dwingen dat alle softwareontwikkeling in koppels wordt uitgevoerd, die bovendien regelmatig van samenstelling wisselen, ontstaat er een collectief 'eigendomsgevoel' en worden peer-review en code-inspectie als van nature onderdeel van het normale softwareproces. Het gevolg is dat het uiteindelijk opgeleverde systeem niet langer bestaat uit een met 'touwtjes' aan elkaar gebonden verzameling van stukjes code, die slecht onderhoudbaar zijn.

Daarnaast is er nog een ander voordeel van deze manier van werken: er zijn altijd minstens twee mensen die ieder stuk code volledig doorgronden. Het inwerken van nieuwe mensen gaat als vanzelf. Er vindt een voortdurende "training-on-the-job" plaats. RSI zal met deze ontwikkelmethodiek minder kans krijgen werknemers te vellen, doordat er afgewisseld kan worden.

Planning

Het planningsproces is het belangrijkste proces. De planning gebeurt eens per week en bestaat uit een releaseplanning en een iteratieplanning.

  • Release Planning: hierbij wordt bepaald welke functionaliteit in welke release gerealiseerd wordt. Zowel de ontwikkelaars als de gebruikers zijn hierbij aanwezig. De Release Planning bestaat uit 3 fasen:
    • Onderzoeksfase (Exploration Phase): hierbij maken de gebruikers een korte lijst met de belangrijkste eisen voor het nieuwe systeem. Dit gebeurt in de vorm van user story's.
    • Concept besluitvorming (Commitment Phase): hierbij wordt besloten welke user story's in de volgende release meegenomen worden en wanneer deze release zal zijn.
    • Wijzigingsfase (Steering Phase): hierbij kan het plan nog worden aangepast en nieuwe story's worden toegevoegd en anderen verwijderd.
  • Iteration Planning: hierbij worden de user story's die in de release planning voor de komende sprint zijn opgenomen uitgesplitst in taken voor de ontwikkelaars. Hierbij zijn geen gebruikers betrokken, alleen ontwikkelaars. Iteration Planning bestaat ook uit drie fasen:
    • Onderzoeksfase (Exploration Phase): de story's worden naar taken vertaald en deze taken worden op kaarten geschreven, zogenaamde taak-kaarten.
    • Toewijzingsfase (Commitment Phase): van deze taken wordt ingeschat hoelang het duurt om dit te realiseren en de taken worden aan de ontwikkelaars (paren) toegewezen.
    • Ontwikkelfase (Steering Phase): de taken worden uitgevoerd en het resultaat wordt vergeleken met de originele tijdsplanning van de userstory.

Het doel van de planning is om te zorgen dat het product afgeleverd kan worden. Het gaat niet zozeer om het afgeven van exacte data als wel om het opleveren van het product.[2]

Releaseplanning

Onderzoeksfase (exploration phase)

Dit is het proces van het verzamelen van vereisten en het inschatten van de hoeveelheid tijd die het kost om die te realiseren. Onderdelen zijn:

  • Schrijf een verhaal (user story): de gebruikers komen met een probleem of wens; tijdens een overleg zullen de ontwikkelaars proberen dit probleem volledig te begrijpen. Op grond hiervan wordt er een user story geschreven. Dit wordt door de gebruikers gedaan, hierbij geven zij aan wat zij van een (gedeelte van) het systeem verwachten. Het is belangrijk dat de ontwikkelaars zich hier niet mee bemoeien.
  • Inschatten van de user story (estimate a story): de ontwikkelaars schatten hoeveel tijd het kost om dit te maken. Door de ontwikkelaars kunnen nu ook korte onderzoeken, "spikes" genoemd, benoemd worden, om delen van het probleem of de oplossingsrichting te onderzoeken. Deze spikes worden gebruikt om tot betere tijdsschattingen te komen en worden weggegooid zodra het probleem en/of de oplossing voor iedereen duidelijk is.
  • Splitsen van een user story: een story moet volledig duidelijk zijn, alle onduidelijkheden moet eruit zijn voordat met de iteratie planning begonnen kan worden. Als de ontwikkelaars wegens onduidelijkheden geen tijdsschatting kunnen afgeven voor de story, moet de story gesplitst worden.

Als de gebruikers al hun wensen hebben beschreven kan men verder met de concept besluitvorming (commitment fase).

Concept besluitvorming (commitment phase)

In deze fase wordt uitgezocht wat de kosten zijn, de opbrengsten en wat voor tijdsconsequenties dat heeft. Deze fase heeft vier onderdelen namelijk:

  • Sorteren op waarde: de gebruikers zetten de user story's in volgorde van wat zij belangrijk vinden.
  • Sorteer op basis van risico: de ontwikkelaars geven een inschatting van de risico's en sorteren de story op basis daarvan.
  • Bepaal de ontwikkelsnelheid (velocity): de ontwikkelaars bepalen met welke snelheid zij dit project kunnen uitvoeren.
  • Scope: er wordt bepaald welke user story's in de komende release worden gerealiseerd. Op grond hiervan wordt de releasedatum bepaald.
Sorteren op waarde voor de gebruikers (business value)

De gebruikers geven de prioriteit aan van de user story's. Zij maken 3 stapels:

  • Kritisch: zonder deze story's kan het systeem niet werken of heeft het geen waarde.
  • Belangrijk: user story's die belangrijk zijn voor het bedrijf.
  • Nice to have: User story's waarmee minder belangrijke eigenschappen worden gerealiseerd.
Sorteren op basis van risico

De ontwikkelaars sorteren de user story's op basis van het risico. Zij maken ook drie stapels: klein, medium en hoog risico. In het volgende een voorbeeld:

  • Bepaal de Risk Index: geef elke user story een index van 0 tot 2 op elk van de volgende variabelen.
    • Volledigheid (hebben we alle details boven tafel?)
      • Volledig (0)
      • Onvolledig (1)
      • Onbekend (2)
    • Kwetsbaarheid (zijn wijzigingen waarschijnlijk?)
      • laag (0)
      • Medium (1)
      • Hoog (2)
    • Moeilijkheid (hoe moeilijk is het te realiseren?)
      • Eenvoudig (0)
      • Standaard (1)
      • Moeilijk (2)

Alle waarden voor de user story worden bij elkaar opgeteld, waardoor de user story een risico waarde krijgt van laag (0–1), medium (2–4), of hoog (5–6).

Wijzigingsfase (steering phase)

In deze fase kunnen de ontwikkelaars samen met de gebruikers het proces "sturen". Met andere woorden, zij kunnen nog iets wijzigen. Individuele gebruiker story's, of de belangrijkheid van de verschillende story's kunnen veranderen; schattingen kunnen verkeerd zijn. Deze wijzigingen kunnen aangebracht worden.

Iteration planning

Afhankelijk van de snelheid van het team kan er bepaald worden hoeveel story punten het team kan doen per iteratie. Iteraties kunnen 1 tot 3 weken duren.

Onderzoeksfase (exploration phase)

Tijdens de onderzoeksfase van de iteratieplanning worden de user story's opgedeeld in taken en van de taken wordt geschat hoelang ze duren. Werkzaamheden:

  • Vertaal de user story's in taken en schrijf deze op taak-kaartjes.
  • Voeg taken samen of splits ze: Als de ontwikkelaar niet goed kan inschatten hoelang de taak duurt omdat deze te groot of te klein is, moet daar iets aan gedaan worden.
  • Schat de taak: maak een tijdsschatting van de uitvoering van de taak.
Toewijzingsfase (commitment phase)

In de toewijzingsfase (commitment phase) van de iteratie planning, worden de taken over de ontwikkelaars verdeeld.

  • Een ontwikkelaar (programmeur) accepteert een taak: elke ontwikkelaar pakt een taak waarvoor hij dan verantwoordelijk wordt.
  • De ontwikkelaar geeft een tijdsplanning: Omdat de ontwikkelaar nu verantwoordelijk is, is hij nu het best in staat om een tijdsschatting te geven.
  • Bepaal de effectieve werktijd (Set load factor): de effectieve werktijd bepaalt het aantal uren dat de ontwikkelaar/programmeur kan ontwikkelen gedurende een iteratie. Bijvoorbeeld, in een 40-urige werkweek, waarin er 5 uren vergaderd wordt, wordt de effectieve werktijd 35 uur.
  • Balancing: zodra alle taken zijn toegewezen wordt er bekeken hoeveel uur elke ontwikkelaar heeft gekregen in vergelijking ook met hoeveel uur hij effectief beschikbaar is (load factor). Dan worden de taken eventueel opnieuw verdeeld om te zorgen dat iedere ontwikkelaar ongeveer evenveel werk heeft. Als een ontwikkelaar te veel werk heeft wordt er iets verschoven.
Uitvoeringsfase (steering phase)

De uitvoering van de taken wordt tijdens de uitvoeringsfase (steering phase) van de iteratieplanning gedaan.

  • Pak een taakkaart: de ontwikkelaar krijgt de kaart met de beschrijving van de taak van een van de taken waarvoor hij zich heeft aangemeld.
  • Zoek een partner: de ontwikkelaar zal een partner zoeken om het samen te ontwikkelen.
  • ontwerp de taak: indien noodzakelijk zal er een (kort) ontwerp gemaakt worden.
  • Schrijf de unit test: voordat er geprogrammeerd wordt moeten alle tests gemaakt worden. Bij voorkeur zijn dit automatische tests omdat die vaak (automatisch) uitgevoerd moeten worden..
  • Schrijf de code: de programmeur/ontwikkelaar maakt het programma.
  • Test het programma: de gemaakte (unit)tests worden uitgevoerd.
  • Refactoring: Pas de refactoringregels toe en zorg dat de code aan de standaards voldoet.
  • Doe de functionele tests/integratietests: Na de unit test worden alle mogelijke andere test gedraaid. integratietests, regressietests etc. De code moet worden aangepast totdat deze aan de tests voldoet.

Test Driven Development

Bij test-driven development (TDD) wordt er eerst getest en pas daarna geprogrammeerd. TDD zegt dat als testen goed is: schrijf dan eerst de testcode voordat je ook maar een regel code (functionaliteit) schrijft.

Binnen XP neemt het schrijven van automatische unittests een belangrijke plaats in. Het schrijven van deze unittests wordt gedaan voordat begonnen wordt aan het daadwerkelijke programma. In test-driven development (TDD) wordt dit: de programmeur maakt één of twee testen, schrijft een stuk programma, maakt een aanvullende testcase, herwerkt het programma tot deze nieuwe test passeert, ontwerpt weer een nieuwe test etc.

Het voordeel hiervan is dat de programmeur verplicht wordt na te denken over de functionaliteit en de uitzonderingen waar zijn programma rekening mee dient te houden, dus eerst denkt over wat het programma moet doen en dan pas hoe het programma zal werken. De tests leggen als het ware de gevraagde functionaliteit vast. Belangrijk is dan ook dat elk programma maar net voldoende functionaliteit bevat om de test te laten slagen. Indien alle tests slagen voldoet het programma dus precies aan de eerder gedefinieerde eisen (deze zijn immers gedefinieerd in de geschreven en geslaagde unittests).

Wanneer refactoring nodig blijkt te zijn, vormen de al geschreven unittests dan ook een garantie dat wijzigingen geen ongewenste neveneffecten veroorzaken in de werking van het programma.

Mocht het nodig zijn om het programma uit te breiden met nieuwe functionaliteit, wordt wederom als eerste begonnen met het schrijven van nieuwe unittests welke de nieuw te schrijven functionaliteit definiëren. Deze nieuwe functionaliteit is pas gerealiseerd als zowel de nieuwe als de oude unittests allemaal slagen.

Als er in een later stadium tijdens een functionele test een 'bug' wordt gevonden, is het schrijven van een unit test, die deze bug aan het licht brengt, het eerste wat wordt gedaan. Een 'bug' is dus eigenlijk geen fout in het programma, wel het ontbreken van de geschikte test.

Eén team

De klant/gebruiker is onderdeel van het (ontwikkel)team en moet dus continu voor vragen beschikbaar zijn; XP stelt dat uiteindelijk alles om code draait bij het maken van software. XP gaat ervan uit dat deze code dusdanig klantspecifiek is, dat de klant zo dicht mogelijk bij het ontwikkeltraject dient te staan. Bij XP wordt ontwikkeld op basis van testcases die de klant samenstelt. Geen functionele specificaties; er zal enkel worden gecodeerd wat de klant wil dat er uit de testcases moet komen. Niet meer en ook niet minder. Bij voorkeur dient een toekomstige gebruiker te allen tijde aanwezig te zijn, zodat ervoor gezorgd kan worden dat de applicatie exact dat wordt wat de klant wenst. Om dit proces zo goed mogelijk te laten verlopen, werkt XP met korte ontwikkelcycli, waarin steeds een aantal geselecteerde testcases wordt geïmplementeerd tot een werkend systeem. Aan het eind van iedere cyclus kan de klant het systeem beoordelen en desnoods de ontwikkeling bijsturen.

Continu proces

Continue integratie

Als integratie en integratietesten belangrijk zijn, integreer de code dan zo vaak mogelijk, liefst meermalen per dag. Zo wordt voorkomen dat er lokaal met verschillende kopieën gewerkt wordt en men langs elkaar heen werkt. Eventuele integratieproblemen worden direct zichtbaar.

Refactoring

Een belangrijke techniek waarmee XP zich verder onderscheidt van traditionele ontwikkelmethodieken is refactoring: het continu herschrijven van de programmacode in kleine precies afgemeten stapjes, zonder dat daarbij de zichtbare functionaliteit wordt aangetast. Refactoring voegt kortom niets aan de functionaliteit toe, maar vereenvoudigt het ontwerp. Door de herschrijfstapjes regelmatig uit te voeren is het overall effect vaak verbluffend. Er zijn inmiddels een zeventigtal herschrijfregels ontdekt en gedocumenteerd. Ze dragen namen zoals "Introduce Null Object", "Replace Temp with Query", en "Replace Conditional with Polymorphism". De randvoorwaarde voor het succesvol toepassen van refactoring is dat er unit tests voorhanden zijn, die automatisch uitgevoerd kunnen worden na iedere herschrijfstap om zeker te stellen dat de functionaliteit niet is veranderd. Voor bijvoorbeeld Smalltalk bestaat er inmiddels een refactoring browser waarmee herschrijfregels automatisch kunnen worden toegepast, zonder dat de gebruiker zich al te zeer om de correctheid hoeft te bekommeren. Refactoring wordt vaak gebruikt als voorbereiding op het doorvoeren van een uitbreiding of verandering van de functionaliteit.

Korte iteraties

De software wordt in een vaste regelmaat in releases van beperkte omvang aan de klant opgeleverd voor beoordeling; Als korte iteratieslagen goed zijn, maak ze dan werkelijk heel erg kort: seconden, minuten, uren, in plaats van weken, maanden, jaren. Een gemiddelde iteratie van XP duurt twee weken, alhoewel dit volgens extremeprogramming.org kan variëren van één tot drie weken.

De cyclus van XP bestaat uit 6 fases: Exploration, Planning, Iterations to Release, Productionizing, Maintenance and Death.

Gedeelde kennis (shared understanding)

Metafoor

Alle teamleden (ontwikkelaars en gebruikers/klanten) delen een gemeenschappelijk beeld van het systeem ('metafoor'); iedereen moet in staat zijn om in simpele woorden het systeem te beschrijven. Het gebruik van "naming conventions" moet daar ook aan bijdragen.

Standaarden

Er zijn codeerstandaarden die bij iedereen bekend zijn en gebruikt worden.

De code is van iedereen

Iedere ontwikkelaar heeft gelijke rechten over alle programmacode. Als ontwerpen goed is, maak het dan onderdeel van ieders dagelijks werk: verbeter het ontwerp stapsgewijs, zodra de noodzaak zich voordoet. Als architectuur zo belangrijk is, laat dan iedereen werken aan het ontwikkelen van de architectuur.

Eenvoud van ontwerp

Als de code van iedereen is en iedereen alles kan wijzigen moet dat ook mogelijk zijn. Als eenvoud goed is, houd dan het ontwerp zo simpel mogelijk. XP werkt veel met het KISS (Keep It Short & Simple)-principe. Wil een systeem makkelijk te veranderen zijn, dan dient het ontwerp zo eenvoudig mogelijk te zijn. Dit is makkelijker gezegd dan gedaan. De traditionele ontwikkelmethodieken hebben geleerd vooruit te denken en bij het ontwerp steeds na te denken over functionaliteit die misschien in de toekomst moet worden gerealiseerd. Maar deze methodieken gaan uit van de veronderstelling dat de kosten voor veranderingen exponentieel toenemen. Daarom hamert XP er op steeds het meest eenvoudige ontwerp te kiezen om de functionaliteit, die nu gerealiseerd moet worden, mogelijk te maken. Eventuele toekomstige uitbreidingen kunnen met XP namelijk zonder de gebruikelijke extra kosten worden doorgevoerd. Tevens blijkt dat bij de realisatie van een doordacht ontwerp maar al te vaak dat het eigenlijk niet (meer) voldoet. Dit kan enerzijds gebeuren doordat tijdens de analyse en het ontwerpen bepaalde details over het hoofd zijn gezien of anderzijds doordat de eisen zijn bijgesteld. Bij XP loopt ontwerp niet voorop, maar volgt het de code. Als eenvoud goed is, houd dan het ontwerp zo simpel mogelijk.

Het welzijn van ontwikkelaars

Het is voor het welzijn van de ontwikkelaars belangrijk dat er met een continue snelheid gewerkt wordt waarbij overwerken een uitzondering is. Mensen zijn creatiever en werken beter als ze uitgerust zijn. Een 40-urige werkweek moet de regel zijn. Dit wordt mede bereikt door korte iteraties, continue integraties en de goede feedback zodat men niet pas aan het eind merkt dat men het niet gaat halen en er lang overgewerkt moet worden. Het welzijn van de ontwikkelaars is een (goed) gevolg van deze methode en draagt belangrijk bij aan de populariteit.

Voordelen

  • Er is een aantal zeer succesvolle projecten bekend, maar er wordt betwijfeld of deze projecten succesvol waren vanwege de kwaliteiten van de mensen die er aan mee deden, of vanwege de kwaliteit van XP.
  • XP claimt dat de kosten voor ontwikkeling niet exponentieel hoeven toe te nemen bij de ontwikkeling van grote systemen.
  • Flexibel.
  • Snel (deel) resultaten.

Nadelen

Er worden vanuit de praktijk de volgende nadelen van XP genoemd:

  • Er dienen strakke afspraken gemaakt te worden omtrent de gebruikersparticipatie om enige vorm van vrijblijvendheid van de gebruikers/klant in de kiem te smoren. Het schrijven van unit tests moet de uitgangssituatie zijn en blijven voor het ontwikkelen van programmatuur. Wanneer gebruikers niet in staat zijn geweest vooraf unit tests te schrijven, eventueel in samenwerking (pairs) met de ontwikkelaars en ontwikkelaars toch alleen doorgaan met ontwikkelen en er dus eigenlijk niet volgens de best practices gewerkt wordt, dan ontstaat er een systeem waar pas laat door de gebruikers over wordt nagedacht, met het risico dat er veel afgekeurd wordt en opnieuw moet.
  • Code ontwikkelen met enkel oog voor de wensen van de gebruikers kan ook problemen geven wanneer een einddoel (tijdstip) in het oog moet worden gehouden. Het einddoel kan ondersneeuwen met de tijdelijke doelen van de te realiseren iteraties. Dit leidt gemakkelijk tot uitloop van de oplevering van het uiteindelijke systeem. Men kan steeds meer erbij bedenken dat veel tijd kost. Veel aandacht van de projectleider is vereist om dit nadeel van XP te managen.
  • Bovenstaande heeft ook zijn weerslag op de verwachtingen van de opdrachtgever. Deze dienen eveneens aandacht te krijgen zolang XP nog geen bekende ontwikkelmethodiek is.
  • Niet elke ontwikkelaar is een teamspeler. Pair programming ligt niet iedereen. Twee junior ontwikkelaars bij elkaar of twee eigenwijze ontwikkelaars kunnen een moeilijke periode hebben.
  • Er worden problemen verwacht bij het ontwikkelen van legacy-code in combinatie met standaardpakketten.
  • Het belangrijkste is misschien wel dat het niet eenvoudig is XP in te voeren omdat de verschillende elementen van XP zo op elkaar ingrijpen. Er wordt alleen een goed resultaat verwacht als XP volledig wordt toegepast.
  • (en) XProgramming.com