I mjukvaruvärlden kan fem år betyda både ett system som fortfarande är mycket väl förberett för fortsatt utveckling och ett tekniskt problem som med varje månad kommer att kosta mer och mer.
Appens ålder i sig är dock ingen anledning att byta ut den.
Detta är en av de viktigaste sakerna att säga från början.
Det finns ingen universell gräns efter vilken en app måste skrivas om från grunden. Det finns system som har fungerat i ett dussintal år och som fortfarande har en rimlig arkitektur, aktuella beroenden, bra dokumentation och en beprövad releaseprocess. Det finns också betydligt yngre appar vars utveckling försvårats av felaktiga arkitekturella beslut, avsaknad av tester, okontrollerade beroenden eller upprepade snabba fixar.
Problemet är alltså inte antalet år.
Problemet är systemets förmåga att fortsätta förändras.
Den viktigaste frågan är inte: "Är appen gammal?"
En bättre fråga är: "Hur mycket kostar nästa förändring oss?"
Om det tar allt fler timmar att lägga till en ny funktion, kräver flera team, manuella tester och kringgående av begränsningarna i den gamla arkitekturen, börjar systemet generera en kostnad som inte syns i koden i sig.
Detta är just ett av de praktiska symptomen på växande technical debt.
Technical debt kan förstås som kostnaden för framtida förändringar som uppstår till följd av tidigare tekniska beslut. Martin Fowler beskriver det som den extra ansträngning som måste läggas när systemet modifieras, när dess interna kvalitet försvårar utvecklingen.
Och just därför kan en app fortfarande fungera korrekt, men samtidigt bli allt svårare att vidareutveckla.
10 funktioner senare ser systemet helt annorlunda ut
Projektets början är ofta enkel.
Ett MVP skapas.
Sedan tillkommer fler krav:
- integration med CRM,
- onlinbetalningar,
- administrationspanel,
- mobilapp,
- nya användarroller,
- rapportering,
- automatiseringar,
- API,
- integrationer med externa tjänster,
- fler språkversioner.
Varje enskild förändring kan vara motiverad.
Problemet uppstår när arkitekturen inte var utformad med den typen av vidareutveckling i åtanke.
Då läggs de nya funktionerna inte längre ovanpå en stabil konstruktion.
De läggs till ovanpå tidigare undantag, genvägar och kompromisser.
Hur märker man att ett system börjar bli gammalt?
Man behöver inte vänta på ett totalt haveri.
Varningssignalerna visar sig mycket tidigare.
1. En ny funktion tar allt längre tid
Förr tog en funktion några dagar. I dag kräver en liknande förändring flera veckor.
Det behöver inte betyda att teamet arbetar långsammare.
Det kan betyda att allt mer tid går åt till att förstå det befintliga systemet och skydda det mot konsekvenserna av förändringen.
2. Varje förändring utlöser en dominoeffekt
En ändring i en modul orsakar problem på flera andra ställen.
Det är ett tecken på att komponenterna är för starkt kopplade eller att ansvarsgänserna mellan dem har definierats fel.
3. Testerna är främst manuella
Om varje större förändring kräver manuell kontroll av dussintals funktioner ökar införandekostnaden.
Problemet är inte själva avsaknaden av automatisering.
Problemet är avsaknaden av möjligheten att snabbt få tillförlitlig information om huruvida något har gått sönder av förändringen.
4. Teamet är rädd för att röra vissa delar av systemet
Detta är en mycket praktisk indikator.
Om det finns moduler som utvecklarna undviker, eftersom "ingen exakt vet vad som händer efter en förändring", är den tekniska risken redan en verklig affärskostnad.
5. Systemet är beroende av föråldrad teknik
Ett gammalt ramverk i sig är inte ett problem.
Problemet uppstår när:
- det inte längre stöds,
- det är svårt att hitta specialister,
- beroenden inte kan uppdateras på ett säkert sätt,
- körmiljön är problematisk,
- integration med nya lösningar försvåras.
Då börjar tekniken begränsa affärsmöjligheterna.
Måste man alltid skriva om appen från grunden?
Nej.
Detta är ett av de vanligaste misstagen i synen på legacy software.
En fullständig rewrite kan vara motiverad, men är ett högriskprojekt.
Ett gammalt system innehåller ofta dussintals eller hundratals affärsregler, undantag och beteenden som inte finns dokumenterade. Om man skriver om det från grunden kan man mycket lätt skapa ett system som är tekniskt nytt men affärsmässigt ofullständigt.
Därför är stegvis modernisering i många fall en bättre lösning.
En del av systemet förblir aktiv, medan andra områden gradvis ersätts av nya komponenter.
Detta angreppssätt är bland annat känt som mönstret Strangler Fig. Det gör det möjligt att modernisera systemet steg för steg, leverera värde tidigare och minska risken med en engångsmigrering av hela lösningen.
När är modernisering meningsfull?
Det är värt att överväga när:
- systemet fortfarande stöder viktiga affärsprocesser,
- arkitekturen tillåter att åtminstone en del av funktionaliteten kan brytas ut,
- data kan migreras eller integreras på ett säkert sätt,
- problemet gäller specifika områden och inte hela konstruktionen,
- appen skapar värde och en total ersättning skulle vara riskabel,
- systemet kan moderniseras stegvis.
Detta är en särskilt bra lösning för system som inte bara kan stängas av i några månader.
När kanske modernisering inte är meningsfull?
Det finns också situationer där ytterligare räddning av ett gammalt system slutar vara ekonomiskt försvarbar.
Till exempel när:
- arkitekturen i grunden är oförenlig med de nuvarande kraven,
- de centrala teknologierna inte längre stöds,
- systemet saknar tillförlitliga tester och dokumentation,
- säkerheten kräver en genomgripande ombyggnad,
- varje större förändring kräver ingrepp i nästan hela systemet,
- det saknas personer som förstår hur det fungerar,
- kostnaderna för drift och vidareutveckling överstiger värdet av fortsatt användning.
Då är det värt att räkna inte bara moderniseringskostnaden.
Man måste också räkna kostnaden för att fortsätta med den nuvarande lösningen.
Den dyraste appen är inte alltid den dyraste att underhålla
Man kan ha ett system vars månatliga drift kostar relativt lite.
Samtidigt kan varje ny funktion kosta mångdubbelt mer än den borde.
Därför säger inte fakturan för hosting, server eller support ännu hur mycket tekniken kostar.
Den verkliga systemkostnaden omfattar också:
- utvecklingstid,
- testtid,
- kostnad för fel,
- implementeringstid,
- kostnad för driftstopp,
- svårigheten att rekrytera,
- säkerhetsrisker,
- kostnaden för förlorad kunskap,
- fördröjning av nya funktioner,
- affärsmässiga begränsningar som följer av tekniken.
Vid en viss punkt slutar tekniken vara ett verktyg som stödjer verksamheten.
Den börjar bli en begränsning för verksamheten.
Hur bör man närma sig beslutet?
Innan beslutet "vi skriver om allt från grunden" fattas, är det värt att genomföra en teknisk granskning.
Den bör åtminstone omfatta:
Arkitektur - hur systemet är uppdelat och hur dess delar kommunicerar.
Kod - kvalitet, komplexitet, upprepningar och särskilt svårunderhållna delar.
Beroenden - ramverk, bibliotek, versioner och deras stöd.
Säkerhet - sårbarheter, hur åtkomst hanteras och risker som följer av föråldrade komponenter.
Tester - omfattningen av automatisering och möjligheten att införa ändringar på ett säkert sätt.
CI/CD - sättet att bygga, testa och driftsätta applikationen.
Data - databasstruktur, migreringar, integrationer och beroenden.
Övervakning - om man vet vad som händer med systemet efter driftsättning.
Utvecklingsprocessen - hur mycket det faktiskt kostar att leverera en ny funktion.
Först på den grunden kan man på ett rationellt sätt överväga tre scenarier:
- vi underhåller och vidareutvecklar,
- vi moderniserar stegvis,
- vi bygger ett nytt system.
Det finns inget enda rätt svar. Det finns däremot ett rätt sätt att komma fram till svaret.
Tekniken bör möjliggöra utveckling, inte blockera den
Bra arkitektur handlar inte om att systemet ser modernt ut.
Det handlar om att man kan ändra det när verksamheten kräver det.
Därför är det värt att se på applikationen inte bara utifrån om den fungerar idag.
Man måste också kontrollera, hur mycket det kommer att kosta att lägga till fler funktioner om ett år, två år eller fem år.
För ett system som fungerar, men som omöjliggör smidig utveckling, kan vara ett betydligt större problem än ett system som helt enkelt behöver moderniseras.
