Efter några år som konsult inom IT har jag stött på flera olika IT-leveranser, företag och branscher. En sak som jag funderat över ett tag, och även diskuterat med kollegor, handlar om hur pass osynligt mycket av det som ett utvecklingsteam levererar är.

Synliga och osynliga aspekter av ett system

Som kund ser man oftast bara ytan av det man beställer: gränssnitt och prestanda. Ser systemet fult ut eller är segt så är det något man som kund direkt upptäcker och kan påpeka.

Andra aspekter, som till exempel kodkvalitet, säkerhet och arkitektur, är mer abstrakta. Hos flera av dem syns inte bristerna för användaren förrän långt senare, när de får påverkan på systemets förvaltningskostnad. De kan visa sig i akuta problem, som att ett system plötsligt blir extremt långsamt efter att det samlat på sig en viss datamängd. Eller mer långtgående problem, som att utvecklingen går allt långsammare och nya buggar introduceras allt oftare. Många beställare känner nog igen sig i symptomen, men jag tror inte att alla förstår de bakomliggande orsakerna.

Min kollega Erik har beskrivit det så här:

Att bygga något som fungerar är enkelt. Utmaningen ligger i att bygga något som håller över tid.

Orsaker till problem

Som beställare förväntar man sig att de saker man beställt levereras med kvalitet. Ett team som agerar oprofessionellt kan dock pressas till att tumma på de osynliga aspekterna, något som över tid kan få katastrofala följder. Orsakerna kan vara flera, en beställare som pressar teamet att leverera i ett ohållbart tempo eller kanske en konsultchef som vill maximera vinsten (på kundens bekostnad). I min erfarenhet är det skrämmande mycket vanligare än vad man vill tro att se kodbaser och lösningar där team har struntat i den långsiktiga förvaltningsbarheten. Vi har ett flertal gånger fått ta över system där andra konsultfirmor kastats ut.

Så i grund och botten så är det alltså utvecklare som inte tagit ansvar för sitt jobb som är orsaken. Om det sen beror på att de inte kunnat göra sitt jobb för att de inte haft tillåtelse, struntat i det, eller helt enkelt inte haft kompetens, låter jag vara osagt. Det skiljer sig förmodligen från fall till fall men ofta tror jag att den verkliga boven är en kombination av press (att leverera funktionalitet eller fixa buggar), bristande externa kontroller, samt ett team som inte sätter stopp.

Det blir lätt för pressade utvecklingsteam att tumma på det som inte syns när ingen ställer dem till svars. Out of sight, out of mind. Att sedan kalla utvecklingen för en misslyckad leverans blir direkt felaktigt, det borde kallas en vanskött leverans.

Hur kan man undvika problemen?

För det första så är det viktigt att inse att det finns osynliga aspekter av ett system och att det är viktigt att man arbetar proaktivt med dem. Försök inte tvinga ut mer funktionalitet innan teamet byggt klart det de redan håller på med, och anställ ett professionellt team som tar ansvar över förvaltingsbarhet.

Jag tror även det är bra att man som beställare har något sätt att kontrollera att arbetet utförs ordentligt. I flera andra branscher använder man sig av besiktningar eller revisioner, och jag tror IT-branschen kan använda sig av något liknande. En myndighet, till exempel, skulle kunna ta in en tredje part med uppdrag att kontinuerligt utvärdera kvaliteten hos det som levereras från utvecklingsteamet. För konsultbolag borde det vara kontraktuellt tvunget att hålla en viss kvalitetsnivå: dålig kvalitet - inget betalt.

Det kan dock vara svårt att helt och hållet förlita sig på att en tredjeparts-revisor ska kunna lösa problemet. Kod kan skrivas på ett nästan oändligt antal sätt och olika utvecklare har olika preferenser. Det blir alltså svårt att göra en objektiv bedömning. Det gäller även att ha koll på att tredjepartsrevisorn inte är jävig, alltså att denne inte har något att vinna på att utvecklingsteamet lyckas/misslyckas. Istället (eller som extra stöd) föreslår jag att man använder sig av verktyg som SonarQube, Qodana, GitHub CodeQL, och liknande, som kan göra kodanalyser på ett automatiserat sätt. Dessa verktyg producerar rapporter som gör det möjligt att mäta kodkvaliteten mer objektivt.

Det finns även verktyg som automatiskt kan göra säkerhetsanalyser och meddela teamet om sårbarheter upptäcks. Trivy och Dependabot är exempel på sådana verktyg.

Att dessa verktyg kan köras automatiserat innebär ytterliggare en fördel: kontinuerlig uppföljning. Detta är viktigt då det innebär att teamet kan upplysas om problem tidigt. Ju snabbare problemen upptäcks, desto lättare (och i förlängningen billigare) blir det att lösa dem. Risken är annars att det finns ny kod som bygger vidare ovanpå den gamla problematiska koden, något som gör det svårare och mer riskfyllt att få in rättningar. Som medskick till detta vill jag också påpeka att om man väljer att använda en revisor istället för ett automatiserat verktyg så bör revisorn vara delaktig i leveransen så att denne kontinuerligt kan lämna feedback till teamet. Att ta in en revisor i efterhand är inget jag rekommenderar då det i princip redan kan vara försent för att göra de förändringar som krävs.

Några skräckexempel

Som avslutning så listar jag här några exempel på saker jag stött på:

  • Företag där hela utvecklingspersonalen säger upp sig. Trötta på att varje dag behöva vada igenom den illaluktande kodbasen så hittar utvecklarna roligare och mer givande jobb på annat håll.
  • Oanvändbara system. System som, hur mycket pengar och utvecklingstid man än slänger på dem, aldrig riktigt lyckas göra det de ska (här kan man fråga sig om utvecklingstiden spenderas på bästa sätt, kanske skulle man tjäna på att jobba med städning ett tag istället för att bara släcka bränder).
  • Systemintegrationer där data ofta försvinner eller skrivs över med gammalt data. Detta kan ske när utvecklingen bara försöker få saker att funka och inte tar hänsyn till saker som meddelandeordning, idempotens, back pressure, persistens och race conditions (det finns en del att tänka på när data ska hållas i synk).
  • Förändringar som borde varit enkla blir jättekomplexa på grund av utdaterade systemberoenden, krypteringsstandarder, eller liknande (som när TLS1.0/1.1 försvann i mars 2021, äldre system kunde behöva stora uppdateringar för att fortsätta fungera).

Fler, riktigt läskiga, exempel finns bland annat på Agila kontrakt:s Wall of Shame