Fragiliteit: Voorkomen is beter dan genezen Arie van Deursen CWI & TU Delft Automatisering Gids 37(50), 10 december 2004. Wanneer is een software-systeem fragiel? Fragiel betekent breekbaar, broos, en makkelijk (per ongeluk) kapot te maken. Maar programmatuur per ongeluk kapot maken --- wanneer doe je dit? Dit gebeurt eigenlijk alleen tijdens onderhoud. Je probeert een nieuwe use case toe te voegen aan een bestaand systeem en moet daartoe op enkele plekken wijzigingen aanbrengen. Daarbij is het moeilijk te overzien wat precies de afhankelijkheden zijn tussen allerlei modules, data-bestanden en processen, en het gebeurt dan snel dat je een essentieel verband tussen bijvoorbeeld twee componenten per ongeluk verbreekt. Zo bezien is fragiliteit een speciale vorm van slechte onderhoudbaarheid. Een fragiel systeem is dermate moeilijk te begrijpen dat de kans groot is dat een software engineer ongewild allerlei bestaande functionaliteit kapot maakt bij het doorvoeren van een enkele kleine wijziging. Fragiliteit is gerelateerd aan complexiteit. Immers, hoe complexer een systeem is, hoe moeilijker het is om aan te passen. Veel systemen zijn echter overmatig complex: de interne complexiteit is vele malen groter dan nodig zou zijn om het externe gedrag (de functionaliteit) te realiseren. Soms is dit met reden gedaan (om extra flexibiliteit te verkrijgen, bijvoorbeeld), maar doorgaans is de extra complexiteit in de loop der tijd ontstaan, en is het oorspronkelijk zuivere ontwerp geërodeerd door de vele wijzigingen die het systeem heeft moeten ondergaan. Over het algemeen is deze extra complexiteit de belangrijkste veroorzaker van de fragiliteit van software systemen. We kennen fragiele systemen als 'legacy': systemen die we van onze voorgangers gekregen hebben en die een geschiedenis van jaren slecht onderhoud achter zich hebben. Maar fragiliteit is niet alleen een kenmerk van oude systemen: ook een nieuwe applicatie met een ondoordacht ontwerp kan zeer duur in onderhoud zijn. Om die reden definiëren Brodie en Stonebraker (in hun boek "Migrating Legacy Systems", 1995) een legacy systeem ook niet als een oud systeem, maar als een "systeem dat zich verzet tegen verandering". Als kenmerk geven ze aan dat dergelijke systemen over het algemeen "brittle" zijn -- broos, breekbaar en fragiel. Valt er iets te doen aan fragiliteit? Een mogelijkheid is renovatie. Zo heeft bijvoorbeeld het Kadaster besloten zijn primaire informatiesystemen te vernieuwen, en daartoe een incrementele aanpak geformuleerd die de bestaande systemen stap voor stap omzetten in een component-gebaseerde oplossing. Waar mogelijk wordt het renoveren van een onderdeel gecombineerd met het opleveren van nieuwe of aangepaste functionaliteit, om zo het draagvlak voor het uitvoeren van de renovatie bij de diverse belanghebbenden te waarborgen. Het belang van een dergelijke incrementele renovatie-aanpak wordt verder toegelicht in het eerder genoemde boek van Brodie & Stonebraker over legacy systemen. Maar, is het wellicht ook mogelijk de kwaal te voorkomen in plaats van te genezen met dure renovaties? Hier biedt een onderdeel van de opkomende wendbare (agile) methodes zoals extreem programmeren en SCRUM een mogelijke oplossing. Centraal in extreem programmeren staat "continuous refactoring" -- het voortdurend bijschaven van het ontwerp en de code van een systeem. In elke iteratie is expliciet tijd beschikbaar om verbeteringen, en met name simplificaties, aan de interne structuur van de programmatuur aan te brengen. Het motto hierbij is: "Do the simplest thing that could possibly work". Het nu al klassieke boek over refactoring van Martin Fowler (Addison-Wesley, 1999) bevat een reeks van kleine verbeterstappen op ontwerp- en codenivo. Ook grotere aanpassingen aan het ontwerp worden als keten van dergelijke kleine stappen geformuleerd. Fowler erkent wel dat het herfactoriseren in de praktijk vaak achterwege wordt gelaten. Hij omschrijft dit als het opbouwen van een schuld. Je kunt er mee wegkomen, bijvoorbeeld vlak voor een urgente release van je produkt. Maar zolang je niet terugbetaalt en de benodigde vereenvoudigingen aanbrengt betaal je rente, in de vorm van de extra kosten die elke wijziging met zich meebrengt. De fragiliteit van een systeem in ontwikkeling of onderhoud kan alleen maar onder controle gehouden worden als als deze tastbaar gemaakt wordt. Helaas bestaat er geen metriek die de fragiliteit van uw systeem uitdrukt in een cijfer tussen 1 en 10. Toch zijn er wel mogelijkheden. Allereerst kan een poging worden ondernomen om achteraf de gevolgen van fragiliteit te meten. Hierbij kan het gaan om tijdsduur of kosten per afgehandeld veranderingsverzoek of probleemrapport, het aantal openstaande problemen, het aantal nieuwe problemen dat per release geïntroduceerd wordt, enzovoorts. Dergelijke metingen kunnen helpen bij bewustwording (we moeten er wat aan doen) en strategiebepaling (welke prioriteiten moeten we stellen). Wat je op deze manier meet zijn onderhoudskosten achteraf. Maar dergelijke metingen zeggen weinig over de oorzaak (het kan fragiliteit zijn, maar ook een slecht proces). Bovendien helpt informatie achteraf niet bij het voorkomen van problemen. Daarom is het belangrijk ook te kijken naar de broncode van het systeem zelf. Er zijn diverse broncode-metrieken bekend (zoals koppeling of McCabe) waarvan empirisch is aangetoond dat deze gecorreleerd zijn aan onderhoudbaarheid en fragiliteit. Dergelijke metrieken kunnen vol-automatisch uit broncode worden afgeleid. Het bijhouden hiervan brengt dus weinig kosten met zich mee, maar levert wel inzicht op in de kwetsbaarheid van een systeem. De absolute uitkomsten van dergelijke metingen en metrieken zijn vaak moeilijk te interpreteren, en niet altijd bijzonder betekenisvol. Maar de trends hiervan over een langere levensduur van het systeem vormen wel degelijk een indicatie of het de goede of de slechte kant op gaat met de fragiliteit, en of deze bijvoorbeeld in de huidige release sneller is gestegen dan in alle voorgaande. Het is dus zaak een systeem voortdurend te monitoren, in plaats van eenmalig een puntmeting uit te voeren. Het aktief monitoren van onderhoudbaarheid en fragiliteit kan op individueel projectnivo, om zo de kwaliteit van een enkel ontwikkeld systeem in de gaten te houden. Beter nog is het dit ook op hoger management nivo te doen, ten einde de fragiliteit van de volledige software portfolio van een organisatie te monitoren, en zo de kosten te beheersen die onvermijdelijk komen bij overmatige fragiliteit. -- Arie van Deursen is onderzoeksleider op het gebied van software renovatie aan het Centrum voor Wiskunde en Informatica en deeltijdhoogleraar software engineering aan de Technische Universiteit Delft. Hij is mede-oprichter van de Software Improvement Group B.V. gevestigd in Diemen.