Een ontwikkelaar is verantwoordelijk voor drie systemen
Ik weet niet meer waar ik de inval had, onder de douche of op de wc of tijdens het tanden poetsen (duidelijk is in elk geval dat het op de badkamer was): een ontwikkelaar is verantwoordelijk voor (ten minste) drie systemen.
Systeem1
Het eerste systeem is, eh, het systeem. Dat ding, je weet wel, waar je aan werkt. De applicatie, bedoel ik: de back-end, de front-end, de microservices, als je althans een microservicesarchitectuur hebt. Het is, kortom, de code. Laten we dat systeem1 noemen.
Een ontwikkelaar is verantwoordelijk voor het gedrag en de structuur van dat systeem. Het gedrag laat zich omschrijven als “de correcte werking”, “het voldoen aan de gestelde requirements” of, breder geformuleerd, “het leveren van business waarde”. De structuur laat zich omschrijven als “de opzet van de code” of “de codekwaliteit”, of “de mate waarin het systeem aanpasbaar is”.
Systeem1 is het meest in het oog springende systeem. Het is het systeem waar de gemiddelde ontwikkelaar het gros van zijn tijd aan besteedt. Je hoeft geen uitzonderlijke ontwikkelaar te zijn om snel in de gaten te hebben wanneer het gedrag van het systeem te wensen over laat (i.e. wanneer het bugs bevat). Maar om oog te hebben voor onvolkomenheden in de vorm, daar komt meer bij kijken. Je moet aanvoelen dat de huidige opzet van de code je remt bij het toevoegen van nieuwe functionaliteiten, en je moet een idee kunnen formuleren van welke opzet daar beter bij zou kunnen helpen. Belangrijker nog, je moet een plan opzetten om van de huidige naar de gewenste situatie te gaan. Zorgdragen voor de structuur van de code, betekent: refactoren – niet eens in de zoveel tijd, maar continu.
Wie geen verantwoordelijkheid neemt voor het gedrag van de code, produceert een door bugs geteisterde bende. Wie geen verantwoordelijkheid voor de structuur neemt, verwijst het systeem binnen de kortste keren naar de almaar groeiende stapel ononderhoudbare legacy. Dat ontwikkelaars verantwoordelijkheid dragen voor de gezondheid van systeem1, hoef je hen over het algemeen dan ook niet uit te leggen.
Systeem2
Er is een tweede systeem, systeem2, waar de ontwikkelaar zorg voor draagt. Dat is het team dat de code onderhoudt. – Huh?
In Learning Systems Thinking (mijn favoriete boek van afgelopen jaar) definieert Diana Montalion “system” als volgt:
A group of interrelated hardware, software, people, organization(s), and other elements that interact and/or interdepend to serve a shared purpose.
Systemen beperken zich in deze definitie dus expliciet niet tot hard- of softwaresystemen. Ook een ontwikkelteam is een groep onderling verbonden mensen die met elkaar interacteren en van elkaar afhankelijk zijn om een gezamenlijk doel te bereiken. Hun doel is: software produceren (die op zijn beurt weer een ander doel dient). En omdat de technieken – de computers, de software, de programmeertaal, etc. – waarmee deze groep hun doel probeert te bereiken, ook onderdeel is van dat geheel, spreekt men vaak van een team als een sociotechnisch systeem.
De kwaliteit van de opgeleverde applicatie is afhankelijk van de kwaliteit van het ontwikkelteam. Als systeem1 onvolkomenheden bevat, als deze bijvoorbeeld stikt van de bugs, dan is dat een teken dat er een probleem is met systeem2. Het zou bijvoorbeeld kunnen dat er onderling te weinig wordt gecommuniceerd, waardoor de front- en back-end van interpretatie verschillen over wat een bepaalde feature behelst. Of het zou kunnen dat de ontwikkelaars de tester overspoelen met werk, waardoor deze fouten over het hoofd ziet.1 Of het zou kunnen dat een gebrek aan psychologische veiligheid ervoor zorgt dat collega’s niet worden aangesproken op onbegrijpelijke of ondermaatse code (zie ook deze blog).
Net zoals dat je code dient te onderhouden, dien je je team te onderhouden. Dit is waar Sprint Retrospectives voor zijn. Tijdens een Retrospective benader je het team als een systeem en zoek je welke elementen in haar huidige configuratie ervoor zorgen dat doelen wel of niet gehaald worden.
Maar let op: net zoals het onderhoud van systeem1 niet beperkt blijft tot één terugkerend uurtje refactoren in de week, dien je het onderhoud van systeem2 niet te beperken tot de Retrospective alleen. Het voelt soms alsof het onderhoud in slecht functionerende systemen het gros van het werk behelst, en daardoor lijkt het alsof goed functionerende systemen geen onderhoud behoeven. Maar dat is gezichtsbedrog: goed functionerende systemen worden continu onderhouden, dat is waarom ze zo goed functioneren.
Systeem3
Maar we hebben het eind van het verhaal nog niet bereikt. Een applicatie en het team dat haar ontwikkelt, bestaan niet in een vacuüm. Systeem2 maakt systeem1 voor iemand (of vaker: iemanden). Dat zijn de stakeholders en (eind)gebruikers van systeem1.2 En die leveren op hun beurt (hoop je!) weer feedback op de huidige staat van systeem1, op wat voor hen werkt en wat niet.
De applicatie, het team, en stakeholders die het team van feedback voorziet voor de volgende iteratie(s) van de applicatie, vormen het derde systeem, systeem3.
Er zijn verschillende manieren waarop je de verhouding tot je stakeholders kunt vormgeven. In de context van Waterval, speelt de communicatie tussen team en stakeholders zich voornamelijk op papier af. En de richting van die communicatie gaat één kant op: de stakeholders specificeren hun wensen en de teams vertalen dat naar software. In de praktijk blijkt dat niet te werken.
In een agile setting is de communicatie tweerichtingsverkeer: het team toont de huidige staat van het systeem, en de stakeholders reageren daarop, en het team stuurt bij op basis van die feedback. Dit is waar Sprint Reviews voor zijn uitgevonden.
Maar ook hier geldt: het is niet zo dat het vergaren van feedback beperkt mag of moet blijven tot formele Review-momenten. Er zijn ook andere manieren om feedback op te halen. Je zou monitoring in kunnen bouwen op het gebruik van je applicatie. Als je een feature vervolgens A/B-test, dan vormt het gebruik door de eindgebruikers van de applicatie zelf het feedbackmoment.
Een ander communicatiemiddel binnen systeem3 is de frequentie waarmee je codewijzigingen deployt en beschikbaar maakt. Laat ik uit mijn eigen ervaring putten. In mijn vorige team was dit een stroperig proces. Een stakeholder meldde bijvoorbeeld een bug, die kwam op een lijst terecht; die lijst werd wekelijks doorgeploegd en geprioriteerd; dan kwam deze op de backlog terecht; als er een fix werd gevonden, ging die naar de testomgeving; daar keek de tester er naar; wanneer die de fix goed bevonden had, ging deze naar de acceptatieomgeving; daar mocht een stakeholder er naar kijken, en pas als die zijn oké had gegeven, werd de fix op productie uitgerold.
Sindsdien ben ik van team gewisseld. Dit is hoe we het nu doen: als er een bug binnenkomt, dan laten we vallen waar we mee bezig zijn en reproduceren we de bug met een test. Zodra die (aanvankelijk falende) test laten we slaagt, rollen we de fix meteen uit op de productieomgeving.
Continuous deployment is niet een praktijk die je introduceert omdat het zo leuk is (hoewel het ook leuk is). Je introduceert het om systeem3 te optimaliseren. Hoe sneller je uit kunt rollen, hoe eerder je feedback kunt omzetten in nieuwe functionaliteit. De technische innovaties die je als team door moet voeren om continu te kunnen deployen, komen alle systemen ten goede – en zeker niet alleen de softwaresystemen.
Toen ik mijn filosofisch retrospectief over de rol van testen in mijn team voorbereidde, grotendeels gebaseerd op deze blog, benaderde ik het team al als systeem, zonder dat ik het op dat moment doorhad. Toen we als team concludeerden dat we inderdaad de tester overspoelden met een onhoudbare hoeveelheid testautomatiseringswerk, deden we een radicale ingreep in het systeem: we maakten de ontwikkelaars verantwoordelijk voor testautomatisering. ↩︎
In het vervolg zal ik, om niet de hele tijd “en (eind)gebruikers” te hoeven zeggen, slechts over “stakeholders” spreken. ↩︎
agile ontwikkeling · communicatie · continuous delivery · feedback · refactoren · samenwerking · software ontwikkelaar (rol) · sprint retrospective · sprint review · systeemdenken · verantwoordelijkheid