Overslaan en naar de inhoud gaan

Fragiele software schreeuwt om creatieve aanpak

De toenemende fragiliteit van moderne software is een zorgwekkend fenomeen. Hoewel we deze trend in allerlei toepassingsgebieden zien, concentreren we ons in dit artikel vooral op grote applicaties, op enterprise-niveau, zoals die tegenwoordig worden gebouwd met moderne applicatieplatformen als J2EE en.Net.
Carriere
Shutterstock
Shutterstock

Fragiliteit is niet een formeel gedefinieerd kwaliteitskenmerk. Maar het woord geeft intuïtief wel aan waar het om draait: moderne systemen zijn vaak kwetsbaar, breekbaar, foutgevoelig en arbeidsintensief, zowel tijdens ontwikkeling als tijdens exploitatie en onderhoud. Minuscule constructiefoutjes (zoals één verkeerd statement) kunnen onverwacht grote consequenties hebben voor het gehele systeem, zoals het falen van transactionele integriteit. Wijzigingen op één plek kunnen plotseling (en onverwacht) problemen veroorzaken in het gedrag op een andere plek. En de oorzaken van problemen op systeemniveau zijn vaak niet gemakkelijk op te sporen. Fragiliteit uit zich verder in het feit dat er veel (en diepe) kennis en ervaring nodig is om systemen te bouwen, maar ook om ze draaiende te houden en aan te passen. En dat laatste is zeker nodig, onder meer om de evolutie in technologie op te vangen. Waar komt die fragiliteit vandaan? Het klinkt als een open deur (want hoe vaak hebben we dit al niet eerder gezegd) maar het is ontegenzeggelijk een feit dat systemen steeds groter en complexer worden. Applicaties moeten immers steeds meer kunnen. Een belangrijke reden daarvoor is de opkomst van het internet en het daarbij behorende streven naar ketenintegratie (B2B, B2C). Zij hebben geleid tot een hausse aan nieuwe toepassingen, mede om allerlei (technische) kanalen te ontsluiten. Daarnaast bestaat er de groeiende behoefte aan samenhang in de informatieverwerking. Via integratiehulpmiddelen worden bestaande (legacy)systemen geïntegreerd en ontsloten voor gebruik in weer andere toepassingen. Het gevolg daarvan is dat de systemen zelf niet alleen groter worden, maar dat we ze ook steeds meer moeten beschouwen in samenhang met veel andere systemen. Daarbij moeten elke keer ook weer keuzes worden gemaakt over verdeling van functionaliteit over allerlei lagen en platformen. Kwaliteitsborging in dit soort ketens is geen geringe uitdaging, zo leert de praktijk. Toch zijn de groeiende (functionele) omvang en complexiteit maar een deel van het verhaal. Het moderne bouwmateriaal - de technologie - speelt ook een rol. Grenzen Veel toepassingen voor ontsluiting of samenwerking via het web en voor integratie met bestaande systemen worden ontwikkeld met applicatieplatformen zoals J2EE en.Net. Dit zijn objectgeoriënteerde raamwerken die gebaseerd zijn op een virtuele machine, en die basisvoorzieningen bieden voor de constructie van moderne (webgebaseerde, integratiegerichte) applicaties. De voorzieningen in die platformen zijn uitgebreid en groeien gestaag. Zo bieden ze componentmodellen (met bijbehorende faciliteiten voor beveiliging, transactieafhandeling, communicatie met databases en automatische gegevensopslag), maar ook voorzieningen voor webgebaseerde user-interfaces, toolkits voor desktop(Gui-)applicaties, allerlei deelraamwerken voor communicatie met legacysystemen, ontwikkeling van webservices, (interfaces naar) messagingvoorzieningen, manipulatie en transformatie van XML-bestanden, systeembeheer et cetera. Toepassingen - inclusief componenten - worden gebouwd door de OO-raamwerken uit te breiden en te parametriseren. Uitbreiden gebeurt door nieuwe code te schrijven die in het raamwerk wordt geplugd, onder meer via overerving of implementatie van interfaces in nieuwe klassen. Parametrisatie wordt gebruikt om (het gedrag van) bepaalde voorzieningen aan te sturen via instellingen. Dit gebeurt typisch door (XML-)configuratiebestanden, property-sets of resources. Op deze manier kunnen we de constructie van de software aansturen, maar ook de verdeling van componenten over systemen (deployment) en zelfs het run-timegedrag beïnvloeden. Tot zover lijkt er weinig mis. Want waar we vroeger moesten kiezen uit talloze ontwikkelplatformen concentreren de ontwikkelingen zich tegenwoordig op de twee dominante platformen. Dat maakt kiezen toch wat simpeler. En verder: was objectoriëntatie niet goed voor het opzetten van grote complexe systemen? Op zich is dat waar. Maar we lijken langzamerhand de grenzen van het mechanisme te hebben bereikt, zo niet overschreden. De raamwerken waar we hier over praten zijn namelijk groot, erg groot. Een willekeurige, kleine steekproef: de run-time van de nieuwste versie van de Java Standard Edition (versie 1.5 sdk) bevat meer dan 12.000 types (interfaces of klassen). Daar zitten weliswaar ook implementatieklassen bij, maar toch, het aantal is indrukwekkend, vooral ook omdat J2EE-faciliteiten hierbij nog niet zijn meegeteld. En voor een echt project/systeem zijn de klassen in de raamwerken zelf meestal al niet meer voldoende. Additionele, soms meer perifere, voorzieningen voor unit-testen of het automatisch bouwen van een systeem, worden veelvuldig gebruikt. Configureerbaarheid is op zich ook een nuttige techniek. Maar ook deze medaille heeft een keerzijde. Het totale gedrag van een systeem wordt nu verspreid over platformcode, eigen code en parameters. En die moeten onderling wel op elkaar afgestemd zijn en blijven. Dit vereist ‘holistisch’ inzicht, ook bij degenen die parameters later mogelijk moeten veranderen. Een bijkomend fenomeen is de evolutie in de platformen. ‘Gestage groei’ is een understatement. Er is sprake van een snelle evolutie in de concepten waar ontwikkelaars mee moeten werken. Ter illustratie: alleen al op het gebied van de web-user-interfaces in de J2EE-sferen zijn er de afgelopen jaren diverse benaderingen ontstaan, waaronder Java Server Pages, Servlets, het Struts-raamwerk en Java Server Faces. En hoeveel ‘standaarden’ rond XML zijn in de afgelopen jaren niet ontstaan (en weer verdwenen)? Het kost de nodige tijd om concepten te laten evalueren en rijpen om tot gebalanceerde oplossingen te komen. Blijkbaar hebben we die tijd niet, want de technologische veranderingen volgen elkaar in sneltreinvaart op. Overigens speelt de open-sourcegemeenschap hierbij ook een belangrijke rol. Binnen een project als Jakarta wordt bijvoorbeeld actief nagedacht over en gewerkt aan steeds betere raamwerken en voorzieningen rond het Java-platform (zoals de zeer populaire Apache-webserver). De resultaten daarvan worden in de praktijk volop gebruikt en vinden hun weg ook weer naar de standaards en producten van de leveranciers. Wat betekent dit alles voor de fragiliteit? ’s Ochtends de legacy van ’s middags bouwen Zoals gezegd: de problematiek waarmee projecten tegenwoordig worden geconfronteerd is inherent al groot en complex en daar komt de complexiteit en evolutie van de technologie nog eens bij. Door de omvang van de systemen en van de platformen zijn foutjes snel gemaakt. Iemand die het totaal niet overziet kan ook niet inschatten wat de consequenties zijn van eventuele fouten die hij maakt bij het programmeren van een onderdeel of bij het bepalen van een configuratiebestand. Vaak manifesteren die problemen zich pas laat en kunnen ze pas worden geconstateerd tijdens systeemtesten en soms zelfs nog later. Verder vereist de evolutie in technologie continue alertheid. Technologiekeuzes hebben beperkte houdbaarheid. Soms moet zelfs tijdens ontwikkeltrajecten worden omgeschakeld. Af en toe lijkt het er zelfs op dat we ’s ochtends de legacy van ’s middags aan het bouwen zijn. De consequentie van dit alles is dat zeer diepe, brede en actuele kennis nodig is van de platformen en hun karakteristieken voor betrouwbare ontwikkeling, exploitatie en onderhoud van systemen. Soms is zelfs kennis nodig over de onderliggende lagen (zoals parametrisatie van virtuele machines of gedrag op specifieke operatingsystemen of machines) om tot een adequaat werkend systeem te komen. Want waar worden bijvoorbeeld performanceproblemen nu precies veroorzaakt? In de code die zelf is geschreven? In de configuratie van de applicatieserver? In de instellingen van de webserver? In de virtuelemachineconfiguraties? Of in de instellingen van het operatingsysteem? Echte experts zijn dun gezaaid. En als ze voorhanden zijn, en zelfs als ze een goed ontwerp van een systeem hebben opgezet, dan nog bestaan er risico’s, namelijk: dat minder onderlegde ontwikkelaars fouten maken die tegen de regels ingaan en het systeemconcept (onbewust) corrumperen, of dat er volgende maand toch een nieuwe versie van het platform of een beter deelraamwerk komt, of dat volgend jaar een beheerder er niets van begrijpt en een verkeerde instelling doorvoert. Hoe gaan we het aanpakken? Er is reeds een aantal ontwikkelingen te zien dat hieraan bij zou kunnen dragen. We noemen de belangrijkste. Met name bij ontwikkelaars lijkt kwaliteitsborging steeds populairder te worden. Middels benaderingen als test-first programming en het gebruik van unit-testraamwerken (zoals junit voor Java) wordt permanent en geautomatiseerd testen steeds meer een standaardpraktijk. Een goede zaak, mits iedereen de noodzaak hiervan ook herkent en erkent zodat de tijd er ook voor vrij wordt gemaakt. Verder is kennisdelen in de wereld van softwareontwikkelaars de laatste jaren gemeengoed geworden. Weer een goede zaak: want ervaringen en best-practices worden volop gedeeld. Op specifieke websites (zoals ‘TheServerSide’) worden ervaringen breeduit besproken en bediscussieerd. Verder zijn de boeken met patronen inmiddels niet meer te tellen. En gelukkig gaan die boeken ook steeds vaker over de ontwikkeling van grootschalige systemen, hoewel soms specifiek voor een bepaald platform. Toch zijn de ‘patterns’ geen ‘silver bullet’. Om een oplossingsrichting te kunnen beoordelen en waarderen moet je namelijk het probleem appreciëren; dus moet de lezer ook al enigszins een ervaringsdeskundige zijn. Het risico daarbij is dat oplossingen te ‘zuiver in de leer’ worden. Zou bijvoorbeeld in sommige situaties vanuit het oogpunt van begrijpelijkheid van een systeem een beperkte mate van duplicatie niet te prefereren zijn boven een zeer fijnmazige verspreiding over lagen of onderdelen? Rond kennisdelen mag ook het fenomeen van de wiki’s niet onvermeld blijven. Een wiki is een website waarvan de lezers de opbouw en inhoud bepalen. De gemeenschap van (expert)ontwikkelaars discussieert al jaren op deze manier over ontwerpvragen en -oplossingen. Ook binnen projecten worden dergelijke wiki’s steeds vaker ingezet. Een andere trend is de simplificatie van de platformen, deels door verrijking van de gebruikte talen, deels door gebruik te maken van technieken als Aspect-Oriented Programming (grofweg: een manier om op specifieke momenten in de executie van programmatuur andere software in te laten grijpen om bepaalde zaken, zoals logging, te regelen). Weer een goede zaak, want de te schrijven software wordt hierdoor simpeler omdat allerlei routinematige code niet hoeft te worden ontwikkeld. Maar ook hier is een keerzijde: een goed overzicht over het totaal blijft nodig om rare verrassingen te voorkomen. Misschien is het een alternatief om echte ‘light’ versies van de platformen te beschouwen: kleine subsets gericht op bepaalde toepassingsgebieden. Een (grote) stap verder is het idee van ‘Model Driven Architecture’, zoals gepropageerd door de Object Management Group. Kerngedachte hierbij is dat we het programmeren verlaten en alleen nog maar modelleren (in UML, met de nodige additionele voorzieningen). De modellen worden dan (in meerdere stappen) getransformeerd naar code voor de bekende platformen. Op zich een aantrekkelijk perspectief: de facto creëren we een nieuwe taal op hoog niveau, die ons beter in staat stelt de werkelijke functionaliteit uit te drukken. De vraag is echter wel of we daar (in de breedte) al klaar voor zijn, zowel qua technologie als modelleerkracht. De vraag is ook of UML daarvoor wel de meest geschikte taal is. Fundamentele verbeteringen Er gebeurt dus al het nodige waarmee we fragiliteit te lijf kunnen gaan. Maar toch blijft er het nodige knagen. Er blijven punten over waarop fundamentele verbeteringen nodig zijn. Het eerste punt betreft de documentatiesystematiek. Dat geldt niet alleen voor de applicatieplatformen maar ook voor de systemen die daarmee worden gebouwd. Vooral als we die systemen beschouwen in hun samenhang met andere systemen. Hoe zorgen we ervoor dat een totale keten goed wordt beschreven? Zo goed, dat ook tijdens exploitatie en onderhoud problemen kunnen worden geïdentificeerd en op de juiste (plekken) wijzigingen kunnen worden doorgevoerd. Hier is een serieuze stap nodig. Een tweede punt is de noodzaak voor stabiele, begrijpelijke en gegarandeerd betrouwbare abstracties. Bouwstenen met een duidelijk beschreven, niet te complexe interface, die ook een gegarandeerde, afgesproken kwaliteit (responsetijd, geheugengebruik, beschikbaarheid, accuratesse, beveiliging et cetera) kunnen leveren, en vrij zijn van onderlinge interferentie. Bouwstenen die zich lenen voor eenvoudige compositie (assemblage) in een groter systeem. Bouwstenen waarvan we bovendien het interfacecontract (functioneel en kwalitatief) kunnen toetsen. De ontwikkeling in decompositieparadigma’s (objecten, diverse componentmechanismen en recentelijk (web)services) kenmerkt zich door steeds grotere bouwstenen en eenvoudigere compositiemogelijkheden. Maar telkens komt ook weer het probleem van adequate interfacebeschrijving en -controlemogelijkheden naar voren. Hoe gaan we dit nu eindelijk eens echt oplossen? Laat duidelijk zijn: er zijn wel goede, betrouwbare bouwstenen en zeker de open-sourcegemeenschap (het Jakarta-initiatief) draagt daar actief aan bij. Maar is het enige antwoord voor het waarborgen van kwaliteit: meer mensen te laten kijken naar de broncode? Biedt dat de fundamentele toetsbaarheid van bouwstenen die we echt nodig hebben? Kunnen we daarmee ook configuraties van componenten of services toetsen? Ook hier moeten we een fundamentele stap zien te maken. Het laatste punt is de filosofie rond systeemontwerp. Het lijkt er te vaak op of tegenwoordig alleen nog maar wordt gedacht binnen de bestaande, gebaande paden. Ongeacht de aard en de omvang van het probleem wordt een (technologische) standaardoplossing voorgesteld. Het bekende verhaal: voor iemand die alleen een hamer heeft ziet de hele wereld eruit als een spijker. In de wereld van de wendbare (agile) ontwikkelmethoden zien we wat verzet hiertegen (in principes als ‘No Big Design UpFront’), maar de focus daarbij is vooral het ontwikkelproces (overigens ook zeer belangrijk). Maar wie denkt er tegenwoordig nog na over echt andere manieren om systemen op te zetten? Wie durft echt andere, en eenvoudigere architecturen voor te stellen? Goeroe’s uit de geschiedenis van softwareontwikkeling hadden het vaak over eenvoud van systemen, over reductie van complexiteit, over ‘less is more’. Deze attitude lijkt zoek, maar is hard nodig om fragiliteit het hoofd te kunnen bieden. Gert Florijn is managing-consultant bij Cibit/Serc ICT Adviseurs, een adviesgroep gespecialiseerd in ICT-architectuur, software engineering en kwaliteit.

Lees dit PRO artikel gratis

Maak een gratis account aan en geniet van alle voordelen:

  • Toegang tot 3 PRO artikelen per maand
  • Inclusief CTO interviews, podcasts, digitale specials en whitepapers
  • Blijf up-to-date over de laatste ontwikkelingen in en rond tech

Bevestig jouw e-mailadres

We hebben de bevestigingsmail naar %email% gestuurd.

Geen bevestigingsmail ontvangen? Controleer je spam folder. Niet in de spam, klik dan hier om een account aan te maken.

Er is iets mis gegaan

Helaas konden we op dit moment geen account voor je aanmaken. Probeer het later nog eens.

Maak een gratis account aan en geniet van alle voordelen:

Heb je al een account? Log in

Maak een gratis account aan en geniet van alle voordelen:

Heb je al een account? Log in