Sådan prioriterer du teknisk gæld

Illustration: Bigstock/REDPIXEL.PL
Adam Tornhill har udviklet værktøjer, der prioriterer teknisk gæld ved hjælp af data fra koderepositories. Bonusinfo om Android og .NET kodekvalitet.

»Det er muligt at kvantificere teknisk gæld med statisk kodeanalyse. Det kan være en interessant, ofte deprimerende, øvelse, men det er ikke nemt at handle på, hvad du finder.«

Ordene kommer fra Adam Tornhill, der i et lille årti har beskæftiget sig med kodekvalitet, teknisk gæld, og hvordan virksomheder bedst kan fokusere på at holde en stadigt voksende og kompleks kodebase under kontrol.

Statiske kodeanalyseværktøjer kan hjælpe en organisation, men ikke meget, mener Adam Tornhill, der ikke anbefaler virksomheder og udviklere at kaste sig hovedkulds ud i en mammutopgave med at komme af med al teknisk gæld.

Tusindvis af issues

»Faren ved kvantificering af teknisk gæld er, at du får en masse information om tusindvis af potentielle problemer i kodebasen. Jeg har set eksempler på statisk kodeanalyse, der identificerer 6.000-7.000 væsentlige issues,« siger Adam Tornhill, der præsenterede på Goto-konferencen i København i slutningen af forrige år.

»Nogle organisationer siger så: 'Lad os investere tre måneder på at nedbringe antallet af issues til 5.000'. Jeg fraråder altid den tilgang. Det er lidt som at springe ud fra 5. sal i stedet for 7. sal.«

Problemet med den tilgang er, at man ikke nødvendigvis får gjort noget ved de problemer, som virkelig betyder noget for forretningen, påpeger han.

»Udviklere vælger at gøre noget ved de problemer, som de kender, de områder af kodebasen, som de føler sig hjemme i.«

Det er ikke nødvendigvis de områder af koden, som er den væsentligste for forretningen.

Projekter med samme mønstre

I stedet anbefaler Adam Tornhill, at man fokuserer på kompleks kode med teknisk gæld, som ændres ofte.

Analyser af et væld af kodebaser viser, at de har samme karakteristika: Langt hovedparten af ændringer sker i et lille antal filer. Kodeforbedringer i de filer bør prioriteres, mens den lange hale bør ignoreres. Illustration: Adam Tornhill

»Kodekompleksitet i sig selv behøver ikke at være et problem, men vi kan bruge det til at identificere kode og så finde ud af, om vi behøver at gøre noget ved koden. Hvis der samtidig er mange ændringer i koden, kan det indikere, at der er tale om et hotspot,« siger Adam Tornhill.

Han har analyseret kildekoden bag en række store softwareprojekter som Erlang, Ruby on Rails og Microsofts Roslyn ved hjælp af sine værktøjer (se boksen ‘Værktøjer til at prioritere teknisk gæld’).

Det viser sig, at de alle har samme mønster, når det gælder hyppigheden af ændringer per fil. Langt de fleste kodeændringer sker i en relativt lille andel af det samlede antal filer i et projekt.

»Jeg har set det mønster i 250-300 kodebaser,« siger Adam Tornhill.

De filer, hvor der ofte foretages ændringer, er dem, der skal fokuseres på, mens filer, der sjældent røres, kan ignoreres – også selvom koden er kompleks.

»Gammel kode er ofte god og stabil kode, da den er blevet hærdet og gennemprøvet,« siger Adam Tornhill og tilføjer med et smil:

Størrelsen af cirklen viser mængden af kode i et modul. Jo større cirkel, des flere linjers kode. Farven for en cirkel viser, hvor ofte der foretages ændringer i modulet. Jo flere hyppige ændringer, des mere rød er cirklen. Her er det ActivityManagerServices.java fra Androids Platform Framework Base, som viser sig at være et hotspot. Illustration: Adam Tornhill

»Gammel kode, der aldrig ændres, kan selvfølgelig være død kode; det er den bedste kode.«

Han understreger, at død kode selvfølgelig skal fjernes.

Teknisk gæld i Android

Adam Tornhill anbefaler, at bruge information fra versionsstyringssystemer og koderepositories til at finde frem til de komplekse metoder og moduler, som ændres ofte.

Som eksempel anvender han information fra Git om Android-kodebasen, specifikt Platform Frameworks Base, som består af 3 millioner linjers kode og har omkring 2.000 udviklere. I Services-komponenten viser ActivityManagerService.java sig at være et hotspot, kode med kompleksitet og mange jævnlige opdateringer.

Vil det være en god ide at refaktorere koden i den fil, spørger Adam Tornhill retorisk og svarer selv nej.

X-Ray af et hotspot zoomer yderligere ind i kodebasen og finder frem til metoder, som der bør ses nærmere på. Det er metoder, der ændres ofte og scorer højt på cyclomatisk kompleksitet. Illustration: Adam Tornhill

ActivityManagerService.java er på næsten 20.000 kodelinjer og er over de seneste tre måneder blevet ændret af 74 udviklere, hvilket gør refaktorering af en så stor kodebase besværlig. Det vil tage for lang tid at refaktorere det hele og koordinere opdateringer med udviklerne.

I stedet zoomer han ind på de enkelte metoder og finder frem til nogle mere overskuelige potentielle refaktoreringsmål.

Det gør han ved at se nærmere på de enkelte metoder/funktioner, og hvor ofte metoden/funktionen ændres samt den cyclomatiske kompleksitet

Personafhængig kode i ASP.NET

Adam Tornhill anvender også sine værktøjer til at identificere kode, som er afhængig af enkelte udviklere.

Hvis en udvikler vælger at forlade en virksomhed, vil det medføre videnstab om koden og dermed gøre det svært at vedligeholde og videreudvikle koden.

Det gælder ikke kun i mindre organisationer.

Adam Tornhill har eksempelvis analyseret Microsofts ASP.NET MVC Core, som er open source. Koden består af 350.000 linjers C#-kode og har omkring 180 udviklere.

»Jeg simulerer, hvad det betyder for viden om kode, hvis en enkelt kerneudvikler stopper,« siger Adam Tornhill og viser, at eksempelvis IntegrationTests har en personafhængighed til en enkelt udvikler.

»Jeg ser det samme mønster i mange andre organisationer. Hvis en nøgleudvikler stopper, vil det have en stor betydning for viden om kodebasen,« siger Adam Tornhill, der med sine værktøjer giver mulighed for at udviklingsorganisationer kan være proaktive og identificere områder af kodebasen, som er meget afhængig af enkeltpersoners viden.

Tips og korrekturforslag til denne historie sendes til tip@version2.dk
Følg forløbet
Kommentarer (26)
sortSortér kommentarer
  • Ældste først
  • Nyeste først
  • Bedste først
Michael Cederberg

Vi har haft diskussionen før: Hvad er teknisk gæld? Er den tekniske gæld som static code analysis finder vigtig? Min erfaring er at det der findes med static code analysis sjældent er specielt vigtigt.

I stedet for at jagte teknisk gæld med automatiserede systemer, så bør udviklere der laver dårlig kode "shames" af dem der reviewer. Det bør være "god stil" at levere ordentlig kode og når man piller ved gammel kode så skal man altid følge "the boyscout rule" (leave code better than when you found it).

Men selvfølgeligt kan et team have glæde af static code analysis. Men teamet selv er bedst i stand til at vurdere hvad der skal prioriteres (ellers er de ikke dygtige nok).

  • 0
  • 0
Ditlev Petersen

I stedet for at jagte teknisk gæld med automatiserede systemer, så bør udviklere der laver dårlig kode "shames" af dem der reviewer.


Konstruktiv kritik er måske mere lærerigt for offeret end shaming?

Jeg sad netop og grublede over noget lignende. Hos os er det bestemte programmer, som få har lyst til at rette i, og som jævnligt brillerer med fejlsager. Programmer der stille og roligt er vokset ud af kontrol.

Man kan såmænd blot læse programmer/modulers navne op, og måle den elektriske modstand i huden på de folk, der arbejder med systemet. Når modstanden falder voldsomt, så har man en grim gældspost.

(Engang på Kommunedata var der en, der nævnte et bestemt program, mens jeg stod med en hånd på en gammeldags tavle. Der kom mindsandten et negativt aftryk fra min hånd, fra sved fra hånden, på tavlen.)

  • 0
  • 0
Michael Cederberg

Konstruktiv kritik er måske mere lærerigt for offeret end shaming?

Man skal finde det rette niveau. Hvis jeg reviewer kode fra folk der sjusker hvor man må forvente mere, så får de at vide at det er sjusk. Hvis det er folk hvor man ikke kunne forvente bedre så får de en mere konstruktiv kommentar. Men det meste tekniske gæld som introduceres uden eftertanke kommer oftest af sjusk. Lavet af folk som burde vide bedre.

Naturligvis er der også teknisk gæld som introduceres efter en velovervejet process. Men det er ikke den slags vi snakker om her.

  • 0
  • 0
Dan Mygind

Ditlev, det er også Adams erfaring, at mange udviklere godt ved, hvor skoen trykker, men de fravælger de "besværlige" moduler, især hvis der afsættes et bestemt tidsrum til at reducere teknisk gæld.
"Nu bruger vi et par måneder på af nedbringe teknisk gæld fra 7000 til 5000 issues"
Så går de efter de lavthængende frugter, hvor de kan vise at de har løst en lang række problemer. Det er bare ikke den tidskrævende og mest komplicerede teniske gæld, der fjernes på den måde.
Det er meget menneskeligt.
Måske skulle Adam tilføje tavletesten til sine værktøjer:
En liste med identificerede Hotspots læses op og det modul, som får udvikleren til at efterlade et svedigt aftryk på tavlen er det første udvikleren går i gang med .

  • 1
  • 0
Dan Mygind

Michael, det kunne være interessant at finde ud af hvorfor folk sjusker. Det er jo ikke noget udviklere gør med vilje.
Er det sidst på eftermiddagen / i slutningen af et sprint at sjuskefejlene opstår? Er det mon noget som I kan aflede vha. versionsstyringssystemet?

  • 0
  • 0
Michael Cederberg

Michael, det kunne være interessant at finde ud af hvorfor folk sjusker. Det er jo ikke noget udviklere gør med vilje.

Der er rigtigt mange grunde ...

  • De fleste software udviklere er rigtigt dårlige til at styre egen tid. Derfor kommer de i tidsnød hen mod slutningen af opgaver. Det leder til sjusk. Kombineret med stramme tidsplaner bliver det rigtigt farligt.
  • Nogle udviklere har en "nu virker det ... løb" filosofi ... at de vil gerne videre til næste opgave så snart de ser det forventede en gang. I stedet for at bruge lidt ekstra tid på at tjekke at alle corner-cases er testet, at klasser og metoder er navngivet ordentligt, etc.
  • Nogle udviklere bruger ikke tilstrækkeligt tid på at finde de rigtige abstraktioner i koden. Det leder til kode der er svært at læse. Måske har de senere i udviklingforløbet opdaget at de burde have gjort det anderledes, men vælger ikke at refaktorere fordi de mener andre opgaver er vigtigere [Jeg refaktorer hver eneste gang jeg opdager noget er galt designet i egen kode ... min erfaring er at det ikke koster ekstra i længden]
  • Nogle udviklere har glemt basale CS skills (fx. algoritmic complexity). Nogen gider ikke forstå de primitiver de arbejder med. Det kan lede til ineffektiv kode ... når det kommer af manglende omtanke så opfatter jeg det som sjusk.
  • Nogle udviklere regner med at der kommer nogen bagefter og rydder op. Det ses i nogle tilfælde når man har en opdeling mellem udvikling og maintenance.
  • (listen fortsætter ... mennesker sjusker)

... og så er der alle de andre grunde til teknisk gæld som ikke har noget med sjusk at gøre.

Er det sidst på eftermiddagen / i slutningen af et sprint at sjuskefejlene opstår?

Jeg har aldrig set at sjusk kommer af træthed. Men jeg har hørt om andre der mener dette.

Du har ikke arbejdet meget med udvikling, vel?

Jeg ved ikke om det var til mig, men jeg har skrevet kode i 35+ år.

  • 5
  • 0
Ditlev Petersen
  • 0
  • 0
Dan Mygind

Næh, som citatfunktionen gerne skulle vise var det til Dan Mygind.

Jeg har arbejdet en del med udvikling og derfor mit spørgsmål om det kunne indkredses, hvad årsagen til sjusk kan være.
Stramme deadlines, ikke helt klar forståelse af krav/systemsammenhæng, ikke tid/manglende lyst til refaktorering - som Michael skriver bliver man nogle gange klogere efter at have skrevet koden - er nogle af mine bud, ligesom jeg helt uden dokumentation tror at mental træthed også kan spille ind. Derfor mit spørgsmål om man eksempelvis kan se om bugs introduceres sent på eftermiddagen.

  • 0
  • 0
Kristian Thy

ligesom jeg helt uden dokumentation tror at mental træthed også kan spille ind. Derfor mit spørgsmål om man eksempelvis kan se om bugs introduceres sent på eftermiddagen.


Selv hvis din første antagelse er korrekt (og det tror jeg ikke), hvilket belæg har du så for at antage at udviklere er mest trætte sent på eftermiddagen? Jeg fungerer personligt ret dårligt før klokken 10, for eksempel.

Min påstand er at langt det meste tekniske gæld (og især det som kan fanges af analyseværktøjer) skyldes en uskøn kombination af

  1. copy/paste-udviklere
  2. udviklere der ikke følger kodestandarder
  3. udviklere der ikke kender nye features i deres programmeringssprog
  4. "it builds, ship it!"-mentalitet hos både udviklere og ledere
  5. time-to-market pres fra ledelsen
  • 1
  • 0
Malik Taaning

Nogle udviklere regner med at der kommer nogen bagefter og rydder op. Det ses i nogle tilfælde når man har en opdeling mellem udvikling og maintenance.
(listen fortsætter ... mennesker sjusker)

Det er også interessant hvorfor folk mener at teknisk gæld nødvendigvis kommer af sjusk....

Her er et par tilfælde der generer teknisk gæld men ikke er sjusk

1: en fornuftig forretningsmæssig beslutning om at nedprioritere kvaliteten af et område af koden med lav impact eller udbytte.
2: en dårlig teknisk løsning vælges MIDLERTIDIGT mens en ny og bedre funktionalitet udvikles
3: ny viden om domænet gør at gamle beslutninger ses som teknisk gæld (e.g forkerte abstraktioner)
4: og mange flere

Så længe vi bliver ved med at betragte teknisk gæld som sjusk, "skam værdigt" etc så kan vi aldrig komme til at snakke ordentligt og struktureret om udfordringen ved at håndtere den.

-

Teknisk gæld skal overvåges og bearbejdes løbende så det ikke kommer ud af kontrol - men som alle andre kvaliteter er der prioriteten ikke simpel.

  • 2
  • 0
Michael Cederberg
  • 1
  • 0
Esben Nielsen

Teknisk gæld := problemer i koden, som besværliggøre videreudvikling; men er kunden ligemeget.

Problemer brugeren kan se er bugs. De kan komme fra, at teknisk gæld har gjort det svært at lave en feature rigtigt; men når først kunden ser problemer er det i min optik ikke teknisk gæld mere, men blot en bug.
Men når det er blevet til en bug ved kunden, er det ofte for sent at ryde op...

Potentielle bugs, som manglende check på størrelsen af en buffer, er i grunden heller ikke teknisk gæld, men bare bugs, som skal rettes, og/eller komme med i "known defects".

Teknisk gæld er svært at få penge til at rette, da det ikke kan ses direkte som nye features eller bugrettelser her og nu. Men rettes det ikke stiger omkostningerne og kvaliteten daler.

Desværre vil pengefolkene ikke rigtigt høre på udviklerne, da det ofte er svært at kvantificere, hvor mange omkostninger en manglende oprydning koster. Lige her og nu ikke ret meget, men i løbet af 2 år??

Vi skal hele tiden tænke på, at gøre det nemt at udvikle videre inden for, hvad kan være realistiske retninger de næste år. Det er ikke et spørgsmål om, at alt koden skal være pæn, have 100% test coverage, men, at arbejdsgangen for at tilføje og få testet en feature, og released en ny version af systemet, skal være så lille som muligt. Teknisk gæld fordyre den cyklus, da ændringer af dårlig kode eller kode uden ordentlige tests giver en masse overraskelser sent i forløbet, som fordyrer tingene voldsomt.

  • 1
  • 0
Malik Taaning

Touche, jeg kan godt se at jeg misrepræsenterer dig (i hvert fald i nogen grad).

Artiklen taler om statisk kodeanalyse - den kigger ikke på hvordan koden er kommet til, men hvordan den ser ud.

Så det er i høj grad både sjusk og velovervejet kode der tales om.

Jeg mener dog stadig at dine kommentarer til OP hælder i retning af at det meste tekniske gæld kommer af sjusk.

Specifikt falder denne kommentar mig for brystet:
"I stedet for at jagte teknisk gæld med automatiserede systemer, så bør udviklere der laver dårlig kode "shames" af dem der reviewer"

Min tolkning af den sætning var i hvert fald at du ser sjusk og dårlige udviklere som den primære kilde.

  • Slutteligt, jeg hodler fast i min pointe - vi skal stoppe med at betragte og snakke teknisk gæld som noget der skal skammes, i hvert fald hvis vi vil det til livs
  • 0
  • 0
Michael Cederberg

Slutteligt, jeg hodler fast i min pointe - vi skal stoppe med at betragte og snakke teknisk gæld som noget der skal skammes, i hvert fald hvis vi vil det til livs

Jeg er ganske enig i at man skal opføre sig ordentligt overfor hinanden på arbejdspladsen. I mit oprindelige indlæg skrev jeg "shames" (i quotes). Jeg vidste godt det var kontroversielt.

Min pointe er at sjusk bedst håndteres gennem social kontrol. Det eneste andet alternativ jeg kender er at sjusk primært håndteres af ledelsen; det betyder at det kun bekæmpes sporadisk (fordi ledelsen ikke ser det hele) og overfladisk (fordi ledelsen ikke nødvendigvis forstår hvad der er sjusk).

  • 0
  • 0
Lars Pedersen

Tit er årsagen til teknisk gæld simpelthen lav IQ.
En datamodel kan have startet godt, men så er der nogle udviklere der skal lave en løsning til en ny feature.

F.eks kan der være en objektmodel med en part-of relation. Nogle udviklere vil lave et produkt som altid består af to dele. I stedet for at udbygge modellen med blueprints som beskriver sådanne begrænsninger, laver de i stedet to nye partstabeller med en 1 til 1 relation.

Mange IQ-tests har opgaver som går ud på at man skal finde et ord som ikke passer ind.

Et tegn på udviklere med lav IQ er hvis en stamdatatabel med ord som tønde, rør, stang etc. pludselig indeholder fastID, komponent, produkt eller andre begreber.

Et andet eksempel er en tabel kaldet Lokation som indeholder hylde, bord, lager etc. Pludselig optræder der sådan noget som rapport, rengøring, huskeliste osv.

Når featuren først er lavet fastfryses datamodellen da systemet nu er live.

  • 1
  • 4
Poul-Henning Kamp Blogger

Så din konklusion, de fleste af dine tidligere indslag taget i mente, må altså være at teknisk gæld skyldes masseindvandring.

Hvis vi lige holder IQ emnet udenfor, så er svaret på det spørgsmål jeg citerer her langt hen ad vejen ubestrideligt ja.

I mellem 1995 og 2000 blev IT industrien overrendt af en sand folkevandring, der findes tilsyneladende ingen blot nogenlunde præcise statistikker, men i runde tal blev IT industrien 1000 gange større i de år, og de 99.9% nye medarbejdere havde ikke skyggen af erfaring eller kendskab til udvikling af IT systemer.

Dot-Com generationen er skyld i rigtig meget Teknisk Gæld.

  • 0
  • 0
Niels Madsen

Poul-Henning,
Mit retoriske spørgsmål, som du her besvarer, var et forsøg på at være morsom. Set her i morgenlysets klare skær, så havde jeg nok gjort klogest i at forbigå den fristelse i stilhed, af hensyn til kvaliteten af debatten i dette forum.

  • 0
  • 0
Ivo Santos

Nu er der så temmelig stor forskel de forskellige progammeringssprog fra 90'erne og fra 2010'erne.
Tag for eksempel C++98 og C++11 eller C++17.
Har nogle af jer f.eks. lyst til at gå tilbage til C++98 frem for f.eks. C++17?
Skal man designe en webside kan det i dag gøres i asp.net. Den mulighed fandtes f.eks. ikke i 90'erne. Eneste mulighed ud over asp var at lave en com dll udvidelse til IIS.

Ligeledes er der jo også en hel del forskelle mellem en linux eller Unix variant fra 90'erne og fra 2010'erne. For eksempel, så er SystemD og SELinux kommet til.

Og så er man vel også blevet en hel del klogere end i forhold til 90'erne. IT er trods alt stadigvæk et ungt fagområde i forhold til f.eks. at stå i en butik eller arbejde med træ.

  • 1
  • 0
Christian Nobel

Og så er man vel også blevet en hel del klogere end i forhold til 90'erne.

Er man?

Nøgternt betragtet er der kommet volumiøse frameworks til, og der laves lystig drag'n'drop programmering, som medfører at selv en "Hallo World" fylder 50MB, og udelukkende kan slæbe sig selv afsted pga. den perverse udvikling der har været i hardware performance.

Men klogere - nahhh.

Skal man designe en webside kan det i dag gøres i asp.net. Den mulighed fandtes f.eks. ikke i 90'erne. Eneste mulighed ud over asp var at lave en com dll udvidelse til IIS.

Det er jo så ikke korrekt.

For det første var Microsoft ret længe om at komme med på vognen, og de er stadigvæk en lille spiller med under 10% af den globalt installerede masse.

Derudover, så blev første version af PHP faktisk releaset allerede i 1995, 7år før asp.net.

Der er, og har altid været, oceaner af andre muligheder end asp.net.

For eksempel, så er SystemD og SELinux kommet til.

Og det kan man så diskutere om er en fordel.

  • 0
  • 0
Michael Cederberg

Har nogle af jer f.eks. lyst til at gå tilbage til C++98 frem for f.eks. C++17?

Man kunne fint skrive ordentlig kode i C++ 2.0 fra 89. Det samme i alle de andre versioner. Ligesom man kunne skrive ordentlig kode i Fortran, Compas Pascal, Microsoft Basic, etc. Det var funktionalitet der manglede i sprogene som man syntes er vigtig i dag, men som man fandt veje udenom som gjorde koden let læselig.

Fx. havde de første versioner af C++ ikke templates. Løsningen var den samme som for C: Fornuftige macroer. Var det lige så godt som templates? Nej. Kunne man skrive kode der kunne genbruges og var let læselig? Ja. Var det fedt at C++ fik templates? Helt sikkert.

Al programmering foregår under de begrænsninger sproget sætter.

Og så er man vel også blevet en hel del klogere end i forhold til 90'erne. IT er trods alt stadigvæk et ungt fagområde i forhold til f.eks. at stå i en butik eller arbejde med træ.

Jeg tror nærmere det handler om at vi har et fagområde som både er meget teoretisk men samtidigt også er meget praktisk. Man kan ikke lære at skrive god kode ved at læse en bog. Der kræves at man samler erfaring og laver dumheder. Personligt har jeg ikke lyst til at blive konfronteret med min første OO-kode i dag. Det var ganske enkelt idiotisk.

Men en god udvikler har også brug for en fornuftigt teoretisk ballast. Jeg husker for mange år siden en ledende udvikler der mente at dobbelt-linkede lister skulle bruges alle steder fordi han havde lavet en god og pæn wrapper omkring samme (det var før den slags kom i standard library). Det var bare dumt og mangel på forståelse af noget så simpelt som algoritmic complexity. I disse år er vi hastigt på vej ud af en tangent med micro-services som nogen ser som silver-bullet til kompleks software arkitektur. Bva.

Helt grønne udviklere mangler typisk enten praktisk erfaring eller teoretisk erfaring eller begge. Når vi laver software projekter og organisationer skal vi huske dette. Men i øvrigt er jeg ganske enig i at kompleks softwareudvikling kræver IQ over gennemsnittet. Og så mener jeg i øvrigt at hvis man kan forstå Knuths værk fra 1968, så er man halvvejs til at blive en dygtig udvikler på det teoretiske plan. Der er ikke sket så meget siden.

... så havde jeg nok gjort klogest i at forbigå den fristelse i stilhed ...

Ja det havde nok været meget klogt. Specielt når overskriften handlede om IQ.

  • 1
  • 0
Log ind eller Opret konto for at kommentere