Deliver at the right quality

Roel Buyzen
9 min readMay 16, 2019

--

Dit is een post in de serie over sneller betere software deliveren volgens 5 principes gebaseerd op mijn eigen ervaringen. Kijk hier voor de introductie en een overzicht van de 5 principes. Vandaag gaan we in op principe 4: deliver at the right quality.

Mijn persoonlijke ervaring met honderden IT-collega’s en nog meer niet IT-collega’s is dat de overgrootte meerderheid van de mensen een goeie job wil doen. Heel erg weinig mensen waar ik mee gewerkt heb kwamen naar hun werk om de kantjes er af te lopen en werk van slechte kwaliteit te leveren. Toch ben ik de afgelopen 10 jaar heel regelmatig in verhitte discussies over kwaliteit terechtgekomen. Hoe kan dat dan?

Het startpunt is dat het begrip kwaliteit niet voor iedereen dezelfde betekenis heeft. Toen ik zelf developer was interpreteerde ik kwaliteit als code kwaliteit en test coverage. Ik gebruikte statische en dynamische analyse tools en was trots te kunnen zeggen wanneer die tools besloten dat mijn code van hoge kwaliteit was. Toen ik voor het eerst in contact kwam met professionele testers bleek dat zij het heel anders bekeken. Voor hen waren het aantal bugs een veel betere definitie van kwaliteit. Enkel software zonder ernstige gekende bugs was software van goede kwaliteit. Daarover vertelden mijn analyse tools erg weinig.

Toen ik management van software teams begon te doen en in contact kwam met mensen hogerop in de organisatie die projecten bekeken vanuit kosten perspectief veranderde er weer wat aan de betekenis van kwaliteit. Op dat moment kwamen de vragen over wanneer de software “goed genoeg” was om live te gaan. En om eerlijk te zijn voelde elk antwoord daarop voor mij erg arbitrair. Wanneer er geen bugs meer zijn van het niveau blocker? Het enige wat dat deed was eindeloze discussies starten over of een bug wel echt blocker was of niet.

Het Rolls Royce-argument

Mijn persoonlijke frustratie ging door het dak toen een directielid op de proppen kwam met het Rolls Royce-argument:

Jullie van IT zijn een Rolls Royce aan het bouwen terwijl wij op zoek zijn naar een degelijke Volkswagen… of misschien een Audi.

De inherente redenering was dat een Rolls Royce duur was en ons project naar zijn gevoel ook. Dat kon volgens hem enkel liggen aan een te hoge focus op kwaliteit. We moesten gewoon bouwen wat goed genoeg was. Niet meer dan dat.

Maar hoe dan? Hoe konden we weten wanneer iets goed genoeg was? Moest dan de code coverage van 100% naar 80%? Of moesten we leven met maar 50 gekende bugs? Wat maakt Rolls Royce-code en wanneer is het Audi-code?

Quality Attribute Requirements (QAR’s)

Gedurende dat ene project zijn we nooit echt uit die discussie geraakt. En dus gingen we naar productie met lagere code coverage en het afgesproken aantal bugs. Maar niemand was trots. Iedereen die aan het project meegewerkt had voelde dat dit wrong. We hadden er gewoon een hoek afgereden. En we vonden het rot.

Pas enkele jaren later reikte een collega met veel meer ervaring me de oplossing voor dit probleem aan. Hij vertelde me over het QAR-framework. Een manier om steeds te werken aan de juiste kwaliteit. Geen Rolls Royces, noch Audi’s. Gewoon “de juiste” kwaliteit voor elk stuk software.

Het eerste wat ik daarin moest leren is dat “de juiste” kwaliteit niet betekent “dezelfde” kwaliteit voor elk stuk software. De beoogde kwaliteit voor twee stukken software kan effectief verschillend zijn afhankelijk van de doelstellingen van de software in kwestie. Maar per stuk software is de beoogde kwaliteit vooraf te bepalen en te meten. De ingenieur in mij was op slag gelukkig.

Hoe werkt het dan?

Het QAR-framework, ook wel Quality Attribute Driven Design genoemd introduceert 4 begrippen: functional requirements, contraints, quality attribute requirements en architectural design sets.

Functional Requirements die kende ik al. Dat zijn de functionele vereisten waaraan een stuk software moet doen. Meestal wordt ze beschreven in de vorm van use cases of van features. Het is een beschrijving van de functionaliteiten die deze software ter beschikking van een gebruiker zal stellen.

Constraints maken deel uit van het kader waarbinnen deze software gebouwd wordt. Het zijn de beperkingen waar we rekening mee moeten houden en die we niet kunnen beïnvloeden. Denk bijvoorbeeld aan de hoeveelheid geld die we mogen uitgeven aan het bedenken en bouwen van deze software. Ook tijd kan een constraint zijn. Sommige stukken software kunnen hun beoogde waarde enkel leveren wanneer ze voor een bepaalde datum opgeleverd zijn. Op dat moment is tijd een geldige contraint.

Quality Attribute Requirements zijn alle vereisten waaraan de software moet voldoen die niet binnen de functional requirement en de constraints passen. Vaak zijn het de onuitgesproken verwachtingen. Het kan gaan over de laadsnelheid van de software, de onderhoudbaarheid, de hoeveelheid gelijktijdige gebruikers die ondersteund moeten worden en zoveel meer. Het zijn de meetbare kwaliteitsparameters die er voor dit specifieke stuk software in deze specifieke situatie toe doen. Er bestaat dus niet 1 vaste lijst van QAR’s. Het vraagt ervaring en kennis van het business domein om te weten welke QAR’s relevant zijn voor dit stuk software.

Wanneer je de relevante QAR’s voor de specifieke situatie te pakken hebt is het belangrijk om voor elke QAR een drempelwaarde toe te kennen. Het niveau dat de software voor deze QAR moet bereiken zodat de software zijn beoogde value kan realiseren. Zo stelde Google CEO Larry Page ooit dat de Google homepagina altijd binnen de 200ms moet laden omdat onderzoek heeft aangetoond dat dat voor het menselijke brein aanvoelt als instant. Dit was dus een heel expliciete en ambitieuze QAR. Maar voor Google was hij erg belangrijk. Google stelt in hun bedrijfs purpose heel duidelijk wat hun definitie van value is: to organize the world’s information and make it universally accessible and useful. Als de Google search engine 2 minuten nodig zou hebben om te laden en nog een 15 minuten om te zoeken wordt het doel van usefulness en accessibility niet bereikt.

Architectural Design Sets maken het QAR-framework volledig. Functional requirements, contraints en QAR’s vormen samen een beschrijving van alle eisen waaraan de software zou moeten voldoen. Maar het is niet gezegd dat het effectief mogelijk is om software te schrijven die aan al die vereisten voldoet. Voor hetzelfde geld zijn sommige van de vereisten helemaal niet met elkaar te combineren. Daarom zijn architectural design sets belangrijk. Wanneer we een duidelijk beeld hebben van alle vereisten bedenken we verschillende oplossingen. Verschillende stukken software die we effectief zouden kunnen realiseren en die zo goed mogelijk voldoen aan de gestelde vereisten. Elk van die bedachte oplossingen is te reduceren tot een architectural design set. De kleinst mogelijke verzameling van architecturele beslissingen waaruit deze oplossing bestaat en die een impact hebben op de gestelde vereisten.

Werken met het QAR-framework bestaat er dan in om alle bedachte oplossingen tegen het licht te houden op vlak van de gestelde vereisten en te beoordelen welke design set het best aan alle verwachtingen kan voldoen. Soms blijkt er geen enkele set helemaal te passen. In dat geval moeten de vereisten herbekeken worden. Kan de beoogde value ook bereikt worden met andere vereisten?

Hopelijk wordt het duidelijker met een voorbeeld

Wat maakt een Audi een Audi en een Rolls Royce een Rolls Royce? Laat me beginnen met te zeggen dat ik niet zo heel veel van auto’s ken. Dit is dus niet bedoeld als een gedetailleerde vergelijking tussen de merken, maar als een voorbeeld van hoe het QAR-framework werkt.

Om dat te kunnen doen moeten we werken met concrete oplossingen. Dus concrete modellen en geen algemene automerken. Voor de duidelijkheid heb ik 1 extra type toegevoegd dat duidelijk verschilt in kwaliteitsattributen.

Functioneel verwacht ik 3 dingen van mijn auto. Dat hij 4 personen kan vervoeren. Dat ik 200 liter bagage kan meenemen. En dat ik er de 200km van en naar mijn werk mee kan rijden zonder onderweg te moeten tanken.

Ik heb 2 constraints. Ik wil graag dat hij binnen de 3 maanden geleverd is en dat hij niet meer kost dan 75.000 euro.

En dan de QAR’s. Om het niet te complex te maken heb ik gekozen voor 3 QAR’s. Ik wil voldoende rijcomfort. Dat betekent voor mij dat ik de 200 km dagelijks kan afleggen zonder dat ik er rugpijn van krijg. Ik wil dat mijn auto betrouwbaar is. Dat uit zich voor mij in het feit dat ik er op kan rekenen dat ik de eerste 4 jaar niet op de pechstrook beland omdat er iets niet goed werkt. Als laatste wil ik graag een beetje zorgen voor het milieu en wil ik dus dat de auto niet meer verbruikt dan 6 liter / 100 kilometer.

Als architectural design sets kies ik voor 3 modellen: de Audi A4, de Rolls Royce Phantom en de Lada VAZ-2101 uit 1970.

Wanneer we de bovenstaande vergelijking kijken en we letten enkel op de functionele requirements zien we dat het moeilijk is om een keuze te maken. Alle 3 de modellen voldoen aan de 3 functionele vereisten.

Voegen we de contraints toe, dan valt jammer genoeg de Rolls Royce af. Dat was ook de manier waarop de directeur van het Rolls Royce-argument naar de vergelijking keek. Maar kiezen we dan voor de Lada of de Audi?

Het is pas wanneer we de QAR’s mee evalueren dat duidelijk wordt wat de beste keuze is. In dit geval is dat dus de Audi.

Er is trouwens een bijkomend interessant punt af te lezen in deze tabel. Bij de Rolls Royce veronderstellen we vanzelf dat hij in alles beter is. Dat blijkt niet het geval te zijn. Omdat we de milieu vereiste toegevoegd hebben als een van de QAR’s is de Rolls Royce niet enkel een probleem op het vlak van contraints, maar ook van QAR’s. Kwaliteit is dus effectief heel erg afhankelijk van de specifieke omstandigheden.

Just enough design, just in time

Je zou kunnen denken dat dit verhaal over het QAR-framework een pleidooi is voor grote big bang projecten met een lange opstartfase waarin een uitgebreide functionele analyse gebeurt gevolgd door een lange QAR-oefening. Niets is minder waar. Zoals je misschien al gelezen hebt in deze post over incremental value delivery geloof ik heel sterk in het tegenovergestelde. Korte iteraties waarna de requirements kunnen veranderen om zo snel mogelijk zoveel mogelijk value op te leveren.

Maar hoe combineer je dat dan met het QAR-framework? Ook dat leerde ik van die meer ervaren collega. De truc bestaat erin om het QAR-framework in te vullen in stappen. Je verrijkt het elke iteratie en beperkt je daarbij tot de beslissingen die op dat moment echt nodig zijn. Neem enkel die beslissingen die niet op een later tijdstip genomen kunnen worden. Want op een later tijdstip beschik je over meer informatie en neem je dus betere beslissingen.

Wat dan met code coverage en bugs?

Wel, dat hangt ervan af. Ben je bijvoorbeeld code aan het schrijven tijdens een 24 uur durende hackathon die als enig doel heeft om een nieuw functioneel concept duidelijk te maken, dan mag je code coverage waarschijnlijk 0% zijn en is het ok als enkel het happy path werkt zonder bugs. Ben je bezig aan code die 10 jaar moet meegaan, regelmatig zal verder evolueren en business kritisch is dan gelden er heel andere spelregels. Net daarvoor dienen de QAR’s. Maintainability en changability zijn QAR’s die vaak gebruikt worden om iets te zeggen omtrent code coverage. Wat te doen met bugs wordt vaak beschreven door meer QAR’s zoals reliability en resilience. Maar er kunnen er meer van toepassing zijn op jouw situatie.

--

--

Roel Buyzen

Operations professional, Delivery management enthousiast, Reverse Nederbelg www.linkedin.com/in/roel-buyzen