-

Technical debt: investeer en voorkom faillissement


“Hoge ontwikkelkosten? Eigen schuld.” Een gewaagde uitspraak die ik de afgelopen jaren een paar keer voorbij heb horen komen. Toch ben ik het er in zekere zin mee eens. Ik ben een developer en ben van mening dat een klant de ontwikkelkosten van zijn applicatie kan verlagen door vaker extra te investeren in de modernisering ervan. Dat klinkt tegenstrijdig: extra geld uitgeven en goedkoper uitkomen. Toch is het zo. Dat heeft te maken met je technical debt. Ik zal je uitleggen hoe dit werkt door je een kijkje te gunnen in de keuken van de developer.

Refactoring

Ik werk al jaren met liefde als developer in de ICT. Ik geniet ervan om projecten ‘from scratch’ op te zetten volgens de laatste code principles met behulp van de nieuwste frameworks. Het op tijd en lean opleveren van een state-of-the-art project geeft voldoening, vooral als het robuust in elkaar zit.

Een paar maanden na oplevering ontstaan er nieuwe wensen en wordt de applicatie uitgebreid. Sommige van deze uitbreidingen zijn zo ingrijpend dat de kernonderdelen van de applicatie herschreven moeten worden zodat een nieuwe solide basis ontstaat waarop verder ontwikkeld kan worden. Dit heet refactoring: het herstructureren van stukken code zonder dat het externe gedrag verandert.

Wat voor de buitenwereld oogt als een eenvoudige uitbreiding kost door refactoring meer tijd dan verwacht en waarschijnlijk begroot. Dit hoeft in principe geen probleem te zijn mits er genoeg tijd en budget beschikbaar is. Is dit er niet dan wordt er soms gezocht naar een goedkope kortetermijnoplossing, op de werkvloer ook wel ‘quick and dirty’ genoemd.

En juist hierin schuilt het gevaar dat dit ten koste gaat van de kwaliteit van de code en op een gegeven moment de applicatie zelf. Je kunt het vergelijken met de bouw van een huis: als je constant muren plaatst en afbreekt zonder te kijken naar de fundering dan zal het huis op een dag in elkaar storten. Refactoren is dus eigenlijk een noodzaak.

Technical Debt

In de ICT gebruiken we de term Technical Debt om aan te geven hoeveel extra werk een aanpassing kost, als gevolg van eerder uitgerolde korte termijn oplossingen. Het is de schuld die je hebt opgebouwd als je in het verleden hebt gekozen voor de quick and dirty aanpak. Hoe hoger de schuld hoe meer werk een aanpassing kost.

Ward Cunningham, een erkende programmeur en uitvinder van de Wiki, legt het ontstaan van het metafoor Technical Debt uit in een kort fimpje:

‘Although immature code may work fine and be completely acceptable to the customer, excess quantities will make a program unmasterable, leading to extreme specialization of programmers and finally an inflexible product. Shipping first time code is like going into debt. A little debt speeds development so long as it is paid back promptly with a rewrite. Objects make the cost of this transaction tolerable. The danger occurs when the debt is not repaid. Every minute spent on not-quite-right code counts as interest on that debt.’ – Ward Cunningham, 1992

De consequenties van een te hoge schuld

Technical Debt ontstaat geleidelijk en het hoeft niet direct bevochten te worden. Als je snel kan deployen door bewust iets in te leveren op de kwaliteit dan kan dat soms een betere keus zijn. Zolang je maar niet te lang wacht met het afbetalen van de opgebouwde schuld. Een te hoge schuld kan vervelende gevolgen hebben:

  • De onderhoudskosten nemen toe. De code is na verloop van tijd moeilijk te doorgronden dus kost het steeds meer tijd om een uitbreiding door te voeren. Elke slechte aanpassing zorgt voor extra complexiteit in de toekomst.
  • Het systeem kan zodanig verouderd zijn dat er weinig developers beschikbaar zijn met de parate kennis van deze technieken. Hierdoor zijn er minder mensen inzetbaar en zal je langzamer kunnen deployen of in het ergste geval helemaal niet.
  • De kosten voor support kunnen hoger worden. Stel je voor dat de hoster van je site geen ondersteuning meer biedt, behalve tegen een hoger tarief en een beperkte SLA. Of dat de koppeling naar het CRM pakket niet meer mogelijk is.
  • Er ontstaan vaker bugs. Dat kan de user experience nadelig beïnvloeden en dan zullen gebruikers een alternatief zoeken.
  • Het wordt minder schaalbaar. Als een verouderd systeem veel traffic genereert en hier geen rekening mee is gehouden tijdens de bouw, dan moeten er flink wat middelen worden ingezet om het draaiende houden. Moderne applicaties ondersteunen daarentegen vaker standaard caching mechanismen.
  • Het mislopen van kansen. Je bent niet agile genoeg om in te springen op nieuwe technologieën. Het oude systeem houdt vooruitgang tegen. Concurrenten kunnen je voorbijstreven.
  • Deadlines worden minder vaak gehaald. Het is voor een developer lastig in te schatten wat hij tegenkomt in een slecht onderhouden systeem. Eenvoudige uitbreidingen kosten dubbel zoveel tijd door slecht samenhangende code.
  • De integratie met externe systemen wordt bemoeilijkt. Moderne applicaties zijn makkelijker te koppelen omdat die dit vanuit de kern al in zich hebben. Voor oude applicaties is vaak maatwerk nodig.
  • Het veiligheidsrisico stijgt. De meeste hacks worden veroorzaakt door verouderde systemen. Eenvoudig op te lossen door regelmatig updates door te voeren waarop de applicatie draait. Maar dan moet dit wel mogelijk zijn, sommige onderdelen kunnen zo verouderd zijn dat automatische updates niet meer vanzelfsprekend zijn zonder de noodzakelijke refactoring.
  • Als de schuld te groot is geworden en een enorme investering nodig is om het product in leven te houden dan is het voor elke partij (opdrachtgever, developer en eindgebruiker) beter om de stekker eruit te trekken.
Verantwoordelijkheid

Er zijn een drietal spelers die invloed kunnen uitoefenen op de Technical Debt en dus de verantwoordelijkheid delen om deze laag te houden:

  • De developer. Hij kan de staat van de code herkennen. Het is zijn taak om de rotte plekken aan te kaarten bij het team, de beslissingnemers of de opdrachtgever. Daarnaast moet hij zelf kwalitatieve keuzes nemen tijdens de bouw.
  • De leverancier van de software moet waken over de kwaliteit van de code. Er moeten tools aanwezig zijn om de kwaliteit te kunnen waarborgen. Junior developers moeten de juiste ondersteuning krijgen.
  • De klant moet de juiste mindset hebben. Hij moet zich bewust worden van zijn product. Het niet zien als kort project maar als een huis waarin mensen willen wonen. Iets wat jaren kan blijven staan. Investeren in renovatie ook al levert dat in de eerste instantie weinig op. Een lange termijn visie verkiezen boven korte termijn oplossingen.
Omgaan met schuld

Technical Debt is nooit helemaal te voorkomen, het is onderdeel van het ontwikkelproces. Het verminderen van de schuld moet ook onderdeel zijn van het proces. Richt je daarom op de volgende zaken:

Verbeter het ontwikkelproces:

  • Voorkom last minute spec wijzigingen, dit zijn vaak de quick and dirty oplossingen omdat er geen tijd of budget meer is. Maak in plaats daarvan een nieuwe release. Gebruik je Scrum? Volg dan strikt de methodiek en maak geen tussentijdse user stories aan als sprints nog lopen. Cancel de betreffende tickets en vul de backlog aan met de nieuwe requirements.
  • Sluit realistische overeenkomsten af. Bugs zijn inherent aan het vak. Er zou na elke oplevering genoeg ruimte beschikbaar moeten zijn om fouten of tweaks zorgvuldig op te lossen. Slecht betaald werk komt het product zelden ten goede.
  • Maak de Technical Debt zichtbaar door een backlog bij te houden. Ook al worden die taken niet direct opgelost tijdens de bouw of erna dan is het toch handig om ergens de staat van de applicatie en de hoogte van de schuld in acties te hebben staan. Programmeurs schrijven in de broncode allerlei to do statements voor zichzelf. Een backlog zorgt ervoor dat deze taken voor iedereen zichtbaar zijn.

Hou rekening met de menselijke factor:

  • Streef naar product ownership. Als niemand zich verantwoordelijk voelt voor de applicatie dan zullen de extra investeringen uitblijven.
  • Zorg voor code ownership bij het ontwikkelteam. Developers denken graag mee over de toekomst van een applicatie als ze zich betrokken voelen. Dit kan bijzonder waardevol zijn als het gaat om het verlagen van de Technical Debt.
  • Probeer mee te groeien met het platform waarop de applicatie draait. Laat het niet verslonzen door onwetendheid betreffende technieken. Raak ermee bekend, volg de technologische ontwikkelingen en haak op tijd aan.

Verbeter de techniek:

  • Omarm continuous integration/delivery. Breng regelmatig nieuwe versies uit van de applicatie in kleine deployments. Feedback van de eindgebruiker kan hierdoor sneller verwerkt worden, wat invloed kan hebben op de lopende werkzaamheden.
  • Zet SaaS oplossingen in. Probeer onderdelen van de applicatie onder te brengen bij externe leveranciers. Zij onderhouden deze stukken code veel intensiever.
  • Maak gebruik van tests: unit-, integration- and acceptance tests. Tests zorgen er voor dat quick and dirty oplossingen sneller worden herkend.
  • Bouw kwalitatieve code: gestructureerd, eenvoudig, uitbreidbaar en duidelijk. Maak gebruik van standaarden zoals frameworks. Probeer niet zelf het wiel opnieuw uit te vinden maar gebruik componenten van derden.
  • Schrijf documentatie zodat iedereen op een later tijdstip weet wat de intentie was tijdens het bouwen van een specifieke feature.
Cost of change

Het laatste wat ik nog wil meegeven is het belang van het tijdig verminderen van de Technical Debt en de kosten die hiermee gepaard gaan. Het moment waarop je overgaat tot het verlagen van de schuld heeft grote gevolgen voor de toekomst. Het is intensiever om een verzamelde berg aan schuld in één keer af te lossen dan telkens kleine beetjes tijdens het ontstaan. De hoeveelheid tijd en geld die een aanpassing kost wordt ook wel de Cost of Change (CoC) genoemd. In onderstaande grafiek zie je duidelijk een relatie tussen de CoC en de Technical Debt:

Wanneer de Technical Debt groter wordt neemt de Cost of Change exponentieel toe en hierdoor vallen de ontwikkelkosten ook hoger uit. Refactor je regelmatig dan blijf je dicht bij de stippellijn. Dat komt omdat elke aanpassing profijt heeft van de vorige.

Conclusie

Je kunt als klant van een softwarebedrijf wel degelijk invloed uitoefenen op de ontwikkelkosten. Je kan dit verlagen door af en toe extra te investeren in de applicatie zodat de Technical Debt niet te groot wordt. Doe je dit regelmatig dan zal de Cost Of Change ook minimaal zijn. Opgebouwde schuld moet je aflossen, net als de schulden bij de bank. Het tijdig aflossen bespaart je geld omdat je minder rente hoeft te betalen.

2017 is gearriveerd. Wellicht een uitgelezen moment om de applicaties eens onder de loep te nemen. Welke verdienen een APK? Praat erover met degene die onder de motorkap kan kijken, die je advies kan geven over de omvang van de Technical Debt. Begin met de applicaties waarvan de onderhoudskosten opvallend hoog zijn, deze zijn verdacht. Wil je de ontwikkelkosten verlagen? Erken de schuld, voorkom faillissement en investeer!

Deel dit bericht

2 Reacties

Hans van der Laan

Het verhaal van Spoel staat als een huis!

Ben Olierook

Erg herkenbaar verhaal. Goed geschreven!

Als je als organisatie je aanpassingsvermogen (wendbaarheid) wil maximaliseren, dan moet technologie met je meewerken en zeker geen bottleneck zijn. Hierin investeren is misschien dan wel financieel pijnlijk op korte termijn, maar het zorgt ervoor dat je überhaupt nog keuzes hebt op de lange termijn. Hoe dichter de applicatie ligt bij de kerncompetenties en het primaire proces van de organisatie, hoe groter de impact van de technical debt op de continuïteit van de organisatie. En wat Colin zegt, als je frequent – in kleinere stapjes – werkt aan de verlaging van je technical debt, dan kan het ook op de korte termijn best meevallen.

Plaats een reactie

Uw e-mailadres wordt niet op de site getoond