NYHET
Del artikkel
Skrevet av: Björn Rudolfsson (Teknisk konsulent i vårt søsterselskap Sylog)
NYHET
Del artikkel
Skrevet av: Björn Rudolfsson (Teknisk konsulent i vårt søsterselskap Sylog)
“Hvis det ikke er ødelagt, ikke fiks det” sier det gamle ordtaket, men når det kommer til programvareutvikling er dette i beste fall et dårlig råd.
Alle som har jobbet mer enn noen år med programvareutvikling vet hvor vanskelig det er å overbevise sjefen om å bruke tid på opprydding og refaktorering (omskriving) av koden. Sett utenifra kan dette virke som et fornuftig standpunkt – tross alt, prosjektet har ikke bedt om endringen, kunden er ikke villig til å betale for det – så hvorfor kaste bort tid på det?
Det er fordi koden som “ikke er ødelagt” koster deg noe, du bare vet det ikke ennå.
Sannheten er at akkurat som industrielt utstyr og finurlig måleutstyr må kildekode vedlikeholdes. Den forringes kanskje ikke med tiden slik som fysiske gjenstander, men gjemt i koden er feil ingen har funnet, dårlige designvalg noen har glemt å rette og mulige forbedringer som bare venter på å bli oppdaget.
Jeg har mistet tellingen på antall ganger jeg har blitt introdusert for kodebaser som har stått nesten urørt i flere år eller til og med tiår. Den gamle “falsk-sannheten” om å ikke fikse det som ikke er ødelagt har fått et dypt fotfeste i mentaliteten vår, og er vanskelig å gå bort ifra.
Jeg tror at mye av skylden går til prosjektfinansieringsmodellen, der alle utviklingsressursene deles ut til prosjekter. Prosjekter har veldefinerte mål og leveranser, og ledelsen har lite interesse for å betale for noe som ligger utenfor omfanget til prosjektet. Dermed blir refaktorering sjelden prioritert.
Å gjøre det på denne måten betyr at kode kun fikses, eller forbedres dersom den inngår i et eksplisitt krav i et prosjekt, eller ved at en feil blir oppdaget. Det er oppriktig overraskende hvor ofte selskaper unnlater å sette av tid og ressurser til generell utvikling og vedlikehold utenfor prosjekter.
Så hva skjer dersom man lar koden stå uten tilsyn eller kjærlighet? Jo, du bygger opp teknisk gjeld, og for å eksemplifisere dette, her er noen typiske feil du vil finne i kodebaser som er dårlig vedlikeholdt og kostnadene som assosieres dem:
Dette er kode som var skrevet for veldig lenge siden, og har gjentatte ganger blitt lappet sammen av en rekke utviklere for å gjennomføre raske korrigeringer. Viktig for denne typen kode er at hver oppdatering har blitt gjort for å kun løse umiddelbare feil oppdaget på stedet med liten eller ingen tanke om hvilke bivirkninger, eller langtids effekter dette kan ha (“det er ikke tid til en ordentlig fiks, bare lapp det til”). Kode pleier å ha lange innviklede metoder som går over flere hundre linjer og dypt nøstede if-setninger. Den pleier å slutte å fungere hver gang det er en stor oppdatering av produktet fordi den er avhengig av annen intern kode og hard-kodede antakelser.
Denne typen kode kan stjele tid og ressurser av flere årsaker; Den vil slutte å fungere når du minst venter det, gjerne når du endrer noe helt uavhengig og kan derfor skape uforutsett arbeid (som forsinker prosjektet); den er ofte vanskelig å forstå fordi den er usammenhengende, noe som gjør implementasjon mer tidkrevende (som forsinker prosjektet); den pleier å lett å i stykker og krever gjerne ekstra ressurser i form av kundestøtte (som forsinker prosjektet og kan få en til å virke upålitelig overfor kunden).
Denne koden har vært der siden tidenes morgen, og har ikke blitt endret siden. Personen som skrev koden forlot bedriften for veldig lenge siden, det finnes ingen dokumentasjon og det er ingen ansatte i bedriften som virkelig forstår hvordan den fungerer. Den er ofte full av linjer som er kommentert ut (uten forklaring), men ingen kommentarer som forklarer den faktiske intensjonen bak koden. Hvis man endrer litt på den, ender det ofte med at den slutter å fungere. Kostnadene ved denne typen kode er litt lumsk; den vil fungere i årevis, til den plutselig ikke gjør det lenger, og da fungerer den aldri igjen. Da er eneste muligheten å skrive den på nytt fra bunnen av, noe som blir dyrt og gjerne krever endringer i andre deler av kodebasen (som vil forsinke prosjektet).
Denne koden var kun ment til å være en midlertidig løsning, og man skulle gjøre en ordentlig implementasjon senere i prosjektet. Dette skjedde aldri, og den midlertidige løsningen ble permanent. Viktig for denne typen kode er at den bare fungerer så vidt, og er holdt sammen av spytt og snøring, eller bare ren flaks. Denne typen kode er ofte grobunn for nye og interessante problemer. Som med den “hellige koden” pleier denne typen kode slutte å fungere på de verst tenkelige øyeblikkene med samme konsekvenser.
Det er selvfølgelig mange typer dårlig kode, og jeg kunne skrevet en rekke artikler om alle, men de tre typene nevnt ovenfor er hvor man typisk ender opp dersom man neglisjerer vedlikeholdsbehovet. Som man kan se er det ikke slik at preventiv refaktorering nødvendigvis er bortkastet tid. Tvert imot kan man sammenligne refaktorering av kode med å sende bilen på service. Bilen vil fungere fint uten, men etter hvert vil små feil begynne på dukke opp, og når den slutter å fungere blir det veldig dyrt.
Så, hvordan skal du introdusere koderefaktorering i ditt selskap? Dette vil være avhengig av selskapet. De fleste utviklere ser verdien av refaktorering, så vanligvis er det ledelsen som trenger å bli overbevist. Det er tross alt de som må betale for det. Det viktige med refaktorering er at det gjøres regelmessig.
Med jevne mellomrom – enten hver eller annenhver sprint hvis dere bruker Agile, eller minst en gang i måneden – velg én komponent eller modul per utvikler som skal refaktoreres. Sett av minst en dag til dette. Hvis det er første gang dere prøver å refaktorere kode, er det en god idé å bruke denne første gangen til å bare gå gjennom hele komponenten og merke seg problemer. Så kan dere begynne på forbedringene neste gang.
Tildel moduler til utviklere som ikke har jobbet med dem før. På denne måten er det nye øyne som ser på koden, og hver utvikler øker sin helhetlige forståelse for hvordan systemet fungerer.
For store og komplekse moduler kan det være smart å refaktorere gjennom parprogrammering, eller ved hjelp av gruppemøter for å diskutere idéer og løsninger.
Det er viktig å få frem at akkurat som ved granskning av kode handler ikke refaktorering om å slenge mest mulig dritt om andres kode, men om å finne muligheter for forbedring. Av den grunn er det viktig at gruppen har en felles eierskapsfølelse til koden. Hvis koden ikke fungerer, må gruppa kunne eie det og fikse den. Å legge skylda på et individ hjelper ikke, selv om det er deres feil. Bruk heller muligheten til å lære vedkommende god programmeringspraksis i tillegg til å fikse problemet. Hvis det er gjort i en konstruktiv ånd trenger ingen å føle seg uthengt, og gruppen vil komme sterkere ut av det.
Sannheten er at det er utviklingsteamet som eier koden, og hvis du ønsker virkelig god kode må du bry deg om koden. Ikke bare selve sluttproduktet eller funksjonaliteten, men den faktiske koden. Når utviklerne bryr seg om koden, og føler et eierskap til den vil de produsere bedre kode, hvilket gir bedre funksjonalitet, og færre feil.
Det er også viktig å skille mellom refaktorering og feilretting. Feilretting er reaktivt – du finner en bug, du fikser den. Refaktorering er proaktivt — du prøver å forbedre koden bare for å gjøre den bedre, for å unngå å få feil i utgangspunktet, som i det lange løp vil være mye billigere. Refaktorering har også en tendens til å se det større bildet, ikke bare fikse spesifikke feil, men revurdere design og implementasjon for å se om du kan gjøre det bedre.
Det morsomme med programvareutvikling er at så snart man har fullført en modul vet du hvordan du skulle løst problemet til å begynne med. Hver utvikler vil kjenne seg igjen i følelsen “Hvis jeg bare visste hva jeg vet nå, hadde jeg gjort det slik i stedet”. Vi har erfart det mange ganger.
Dette er faktisk et kjent konsept i forfatterverden også. Du skriver et førsteutkast for å få ned idéene dine, og deretter reviderer du utkastet, ofte flere ganger, til du får et ferdig produkt. Som forfatter Neil Gaiman sier:
“The process of doing your second draft is a process of making it look like you knew what you were doing all along.”
Dessverre får vi sjelden den muligheten som utviklere, vi blir tvunget til å gi ut førsteutkastet vårt som et ferdig produkt. Og, det er nettopp derfor refaktorering er så viktig! Det gir deg muligheten til å revidere implementasjonen din med visdommen av etterpåklokskap.
Å gjøre andreutkastet, er å gjøre det riktig.
R&D Manager