Net-Base Magasin

14.07.2026

Refaktorera legacykod i Delphi: minska risker, öka underhållbarheten, säkra driften

Etablerade Delphi-applikationer är ofta affärskritiska – men varje liten ändring blir dyrare. Detta inlägg visar hur du refaktorerar legacykod i Delphi utan att äventyra driften: med tydlig kartläggning, prioriterade åtgärder, tester, data- och...

14.07.2026

Från magasinets tema till projektpraxis

Passande tjänste- och tekniksidor för inlägget

Video-Botschaft

Refaktorera legacykod i Delphi: minska risker, öka underhållbarheten, säkra driften

Kurze Einordnung, warum kontrolliertes Refactoring bei geschäftskritischen Delphi-Systemen Betriebssicherheit und Änderungsfähigkeit verbessert, ohne einen riskanten Rewrite zu starten.

Video mit KI erstellt

Transkript anzeigen

Hallo. Kurz ein Thema, das im Betrieb schnell teuer wird.

Der Beitrag heißt: „Legacy-Code in Delphi refactoren: Risiken senken, Wartbarkeit erhöhen, Betrieb sichern“. Wenn jede kleine Änderung ein potenzieller Ausfall ist, werden Releases langsam, und niemand fasst das System gern an.

Legacy heißt hier nicht nur „alt“. Es heißt: schwer erklärbar, stark verknüpft, und dadurch riskant.

Refactoren bedeutet: umbauen, ohne das Verhalten zu ändern. Also kein Rewrite, sondern ein kontrollierter Umbau am fahrenden System.

Wichtig für Admins und IT-Leitung ist die Reihenfolge: erst Bestandsaufnahme. Was ist geschäftskritisch?

Wo hängen Datenbank, Schnittstellen und Jobs dran? Dann kleine, priorisierte Schritte, abgesichert durch Tests und sauberes Logging, damit Fehler auffallen, bevor Nutzer sie melden.

Wenn Sie dazu Fragen haben, schauen wir es gern gemeinsam an.

Den som driver en affärskritisk Delphi-applikation känner till dilemmat: den fungerar stabilt, återspeglar kärnprocesser och är djupt integrerad i databaser, gränssnitt och arbetsflöden. Samtidigt ökar ändringsinsats och risk för varje release, eftersom kompromisser, specialfall och beroenden har byggts upp under åratal. Det är här som refaktorering av legacy-kod i Delphi kommer in: inte som ett „Rewrite“-projekt, utan som en kontrollerad ombyggnad av ett system i drift – med mätbara effekter på underhållbarhet, releasesäkerhet och drift.

I praktiken misslyckas refaktorering sällan på grund av Delphi i sig, utan på grund av bristande transparens: vad är affärskritiskt? Var finns tekniska skulder (det vill säga strukturella brister som fördyrar framtida ändringar)? Vilka delar får beröras under underhållsfönster och vilka inte? Och hur förhindrar man att „städning“ skapar nya fel eller prestandaproblem i produktion? Detta inlägg beskriver en praktisk metod som tar med IT-ledning och administration: från inventering via arkitektur- och datafrågor till tester, releaseprocess och säkerhetsfrågor.

Vad betyder „Legacy“ i Delphi-projekt egentligen?

„Legacy“ jämförs ofta med „gammalt“. I företagskontext är legacykod emellertid primärt kod vars ändringsrisk är hög och vars beteende bara delvis kan förklaras. Det kan vara en VCL-applikation (Visual Component Library, klassisk Windows-desktop-UI), men också en tjänst, en schemaläggare eller ett klient-server-system.

Typiska legacy-kännetecken i Delphi-miljöer är:

  • Stark koppling: UI, dataåtkomst och affärslogik är ihopblandade; ändringar ger sidoeffekter.
  • Implizita regler: Affärslogik ligger i händelser, globala variabler eller databas-triggers, inte i tydliga moduler.
  • Föråldrade dataåtkomster: t.ex. BDE (Borland Database Engine) eller proprietära komponenter; saknade pooling-/timeout-strategier.
  • Oenhetlig felhantering: undantag fångas och tystas, meddelanden hamnar inte i central loggning.
  • Fragilitet i Build och Release: beroenden, sökvägsproblem, olika kompilatorinställningar, manuella efterarbeten.
  • Avsaknad av tester: kunskap finns i huvuden eller i den „klicksekvens“ som erfarna användare utför.

Viktigt: legacykod är inte automatiskt „dålig“. Ofta är den ett resultat av tidspress, teknologicykler och pragmatiska beslut. Refaktorering är då en investering i hanterbarhet – ur drift-, säkerhets-, compliance- och förändringstaktsperspektiv.

Refaktorering vs. Rewrite: Vad som ändras för drift och risk

Ett Rewrite (nyutveckling) lovar en ren start, men medför ofta långa parallella faser, nya felklasser och höga migrationsrisker. Refaktorering däremot syftar till inkrementell förbättring vid kontinuerlig leveransförmåga. För IT-drift och verksamhetsområden är det ofta den avgörande skillnaden: systemet förblir produktivt och förbättringar levereras i hanterbara paket.

Praktisk avgränsning:

  • Refaktorering: Strukturer förbättras, externt beteende ska förbli oförändrat. Fokus: underhållbarhet, testbarhet, stabilitet och prestandareserver.
  • Restrukturierung/Modernisierung: ytterligare riktade beteendeförändringar, t.ex. nya gränssnitt, ny databas, nya plattforms­mål.
  • Omskrivning: ny kodbas, oftast ny UI/arkitektur; kräver migrering av data, processer, gränssnitt – ofta „Big Bang“ eller lång övergångsperiod.

För beslutsfattare är denna punkt central: Refaktorering är ingen självändamål, utan en hävstång för att reducera ändringsrisker. Det är direkt driftrelevant när applikationen påverkar 24/7-processer, produktionsnära flöden eller kundnära portaler.

Legacy-kod i Delphi refaktorera: Starta med en tillförlitlig nulägesanalys

Det första steget är inget verktyg utan en gemensam bild av risker och mål. Utan denna bild blir refaktorering snabbt ett „vi städar upp här“ – och just det är svårt att motivera i drift.

1) Kartlägg kritikalitet och driftrealitet

Kartlägg vilka delar som verkligen är affärskritiska: dagsavslut, gränssnitt till ERP/DMS/CRM, insamling av produktionsdata, fakturering, behörighets­hantering. Komplettera med driftparametrar: underhållsfönster, rollback‑möjligheter, övervakning, datavolymer, latenskrav.

Hjälpsamma vägledande frågor:

  • Vilka funktioner måste fortsätta fungera även vid delvisa fel (degraderingsförmåga)?
  • Var finns „Single Points of Failure“ (t.ex. en central schemaläggare)?
  • Vilka data är regulatoriskt eller dataskyddsmässigt känsliga?
  • Vilka integrationer är mest störningsbenägna (filimporter, TCP/IP, SOAP/REST, messaging)?

2) Gör teknisk skuld synlig – inte bara kodstil

I Delphi-projekt är teknisk skuld ofta arkitektonisk: globala tillstånd, cykliska enhetsberoenden, svårt testbara dataåtkomster eller UI‑händelser som „orkestrering“. Metriker (t.ex. komplexitet, enhetsstorlek, beroendegraf) hjälper, men är bara värdefulla om de översätts till åtgärder.

En praktisk 2×2‑matris är:

  • Ofta ändrat & riskfyllt: högsta prioritet för refaktorering.
  • Ofta ändrat & lite riskfyllt: förbättra processer/tester, mindre strukturella åtgärder.
  • Sällan ändrat & riskfyllt: stabilisering/säkring (tester, loggning), inte nödvändigt att „göra fint“.
  • Sällan ändrat & lite riskfyllt: medvetet lämna orört.

3) Inventera beroenden: data, gränssnitt, körtid

För administration och projektansvariga är det avgörande vad som hänger utanför koden: databasbackends, ODBC/OLE DB, filresurser, utskrifts‑ och PDF‑flöden, COM/ActiveX, Office‑automatisering, Windows‑tjänster, schemalagda uppgifter, certifikat, proxykonfigurationer.

Här uppstår kostnader för refaktorering ofta indirekt: en „liten“ ändring kan tvinga fram ny installerlogik, nya rättigheter eller nya brandväggsregler. Dessa sidoeffekter bör tidigt dokumenteras i en teknisk karta.

Typiska problemområden i Delphi-legacy och hur man hanterar dem målmedvetet

Refaktorering blir hanterbart när den riktas mot återkommande mönster. Följande områden är i praktiken ofta de största risk‑ och kostnadsfaktorerna.

Monolitiska Forms: när UI:t håller ihop systemet

Många VCL-applikationer har historiskt vuxit fram som „formdrivna“: formuläret laddar data, kontrollerar regler, skriver tillbaka, triggar rapporter och uppdaterar andra formulär. Det fungerar – tills flera team eller flera års ändringshistorik möter det.

Ett operativt beprövat tillvägagångssätt är att successivt avlasta UI:

  • Inför use-case-nära tjänster: affärsoperationer som tydligt namngivna metoder istället för händelsekedjor.
  • Inkapsla datatillgång: Queries/Transaktionen inte i UI-händelser utan i dataåtkomstlager.
  • Använd DTOs/Modeller (enkla dataobjekt) för att separera formulärstatus från databastatus.

Målet är inte „mönsterrenhet“, utan bättre testbarhet och färre sidoeffekter: en ändring i validering eller beräkning ska inte äventyra hela UI-klickflödet.

Modernisera datatillgång: BDE ersätta, FireDAC konsekvent använda

Om BDE eller oenhetliga datakomponenter fortfarande används är refaktoreringen ofta samtidigt en modernisering av driftsrisken. BDE är inte bara gammal utan ofta svår att drifta: drivrutiner, konfiguration, 32-bitarsberoenden och saknade moderna säkerhetsmekanismer.

BDE-Ablösung mit nativer Anbindung (Delphis moderne Datenzugriffsbibliothek) är i många scenarier en rimlig standard om man arbetar konsekvent: enhetliga connection-parametrar, tydliga transaktionsgränser, timeouts, pooling och ren exception-hantering. Typiska refaktoreringsåtgärder inom detta område:

  • Förenhetliga anslutningshantering: central factory/provider istället för „varje formulär har sin Connection“.
  • Gör transaktioner explicita: Begin/Commit/Rollback som en del av use-caset, inte dolda i UI.
  • Använd parameteriserade queries konsekvent för att minska risker för SQL-Injection och problem med specialtecken.
  • Definiera timeouts och retries så att nätverksstörningar inte leder till „frusna“ formulär.

För IT-drift är det viktigt att nya connection-strategier samordnas med databashanteringen (t.ex. maximala anslutningar, poolstorlekar, deadlock-hantering, underhållsfönster för schemaändringar).

Unit-Abhängigkeiten und „globale Zustände“ als Hauptursache für Seiteneffekte

Delphi-Units med stora interface-sektioner, många Uses-inlägg och globala singletons är typiska acceleratorer för sidoeffekter. En liten ändring i en Unit orsakar ombyggnadskaskader eller bryter dolda initialiseringssekvenser.

Pragmatiska steg som visat sig fungera i legacy-projekt:

  • Fastställ beroenderiktningar: t.ex. UI → Application Services → Domain/Logik → Data Access → Infrastruktur.
  • Centralisera initialisering: tydlig startup-sekvens istället för Unit-Initialization som dold styrning.
  • Minska globala variabler: håll tillstånd i objekt, klargör livslängd och ownership.

Det betalar av sig i stabilitet: om uppstarten är deterministisk är fel efter uppdateringar eller konfigurationsändringar bättre hanterbara.

Threading und Synchronisation: Stabilität vor „Performance-Optimierung“

Många legacy-applikationer blir över tid samtidiga: bakgrundsimporter, polling, kommunikation med enheter, parallell bearbetning. Utan klara regler uppstår deadlocks, UI-hängningar eller race conditions (åtkomstkonflikter vid samtidig körning).

För drift och support är det ett problem eftersom det ofta orsakar „icke-reproducerbara“ fel. Refaktorisering bör här inriktas på standarder:

  • Tydligt ägarskap för trådar/uppgifter och definierad avstängning (så att uppdateringar/avslut inte fastnar).
  • Loggning per worker med korrelations-ID för att kunna följa flöden.
  • Minimera synkronisering och kapsla strikt åtkomst till UI (UI-trådregeln).

Om ni vill fördjupa er går det att lägga in en intern länk till ett inlägg om robusta mönster med TThread och Synchronize, eftersom ämnet vid legacy-refaktorisering ofta är flaskhalsen för stabilitet.

Arkitekturmålbild: Layering som verktyg, inte som dogm

En praktikabel målbild för många Delphi-beståndslösningar är en tydlig lagerstruktur (ofta förstådd som „3-skikt“): presentation (UI), applikationslogik (Use Cases/Services) och dataåtkomst (Repositories/DAO). Viktigt är den operativa perspektivet: Layering förenklar tester, uppdateringar och senare utskopning av gränssnitt.

Konkreta fördelar för företag:

  • Komplettera gränssnitt (t.ex. REST-API), utan att UI-logik behöver kopieras.
  • Delmodernisering: databasbyte eller BDE-Ablosung mit nativer Anbindung-omställning kan samlas i ett lager.
  • Underhåll: fel kan avgränsas snabbare eftersom ansvar i koden är tydligare.

En realistisk målbild tar hänsyn till att legacy-system sällan blir „rena“. Avgörande är att riktningen är rätt och att nya ändringar inte luckrar upp strukturen igen.

Teststrategi för Delphi-refaktorisering: Hur ni fryser beteendet innan ni bygger om

Refaktorisering utan tester är i affärskritiska system en risk. Samtidigt är fullständig testautomatisering ofta inte realistisk på kort sikt. Den centrala idén är därför: testa riktat där risken och förändringstrycket är högt.

Golden Master och regression: Praktiskt för legacy

En ‚Golden Master‘ är en referens för det aktuella beteendet: indatan och förväntade utdata registreras för att upptäcka avvikelser efter ändringar. Det lämpar sig för rapporter, beräkningar, exporter, importpipelines eller svar från gränssnitt.

Viktigt för driften: Golden-Master-test reducerar risken att sidoeffekter visar sig först efter rollout — och de stödjer snabba hotfix-beslut eftersom avvikelsen blir konkret mätbar.

Integrationstester kring databas och gränssnitt

Många fel uppstår inte i ren affärslogik utan vid systemgränser: transaktioner, Encoding (t.ex. Unicode), tidsstämplar, decimalavgränsare, behörigheter, nätverksstörningar. Integrationstester bör därför åtminstone täcka följande punkter:

  • Transaktionsbeteende vid fel (rollback, deluppdateringar, låsningar).
  • Encoding vid import/export (CSV, XML, JSON), särskilt för specialtecken.
  • Prestandaprofiler för typiska datamängder för att upptäcka gradvisa försämringar.

Manuella testfall kvarstår — men strukturerade

Där automatisering (ännu) saknas hjälper strukturerade manuella testplaner som kopplas till releaser. Ur administrationssynpunkt är det relevant att testfallen även innehåller driftsaspekter: installations-/uppdateringsväg, behörigheter, konfiguration, logging/övervakning, skrivare/PDF, nätverksvägar.

Data och migrering: Refaktorisering avgörs ofta av databasens schema

I Delphi-system har databassstrukturer vuxit fram över år. Refaktorering kolliderar ofta med „historiska“ tabeller, dubbla fält eller domänmässigt överlastade kolumner. Den kritiska punkten: schemaändringar påverkar drift, backup/restore, replikering, rapportering och gränssnitt.

Göra schemaändringar planbara

En beprövad metod är en tydligt versionerad databas-migrationsprocess: varje ändring av schemat dokumenteras som ett reproducerbart steg, inklusive rollback-strategi. Även om migrationer initialt utförs manuellt är disciplin avgörande: inga „vi ändrar snabbt i produktion“.

För releassäkerhet bör ni fastställa:

  • Behov av driftstopp: möjlig online-migrering eller krävs ett underhållsfönster?
  • Återställningsstrategi: datakompatibilitet vid rollback, backup före migration, återstartplan.
  • Kompatibilitetsfas: applikationen kan under en övergångsperiod arbeta med både gammalt och nytt schema (t.ex. extra kolumner, vyer).

Underskatta inte datakvalitet och rensning

En refaktorering avslöjar ofta dataproblem som tidigare „flutit med“: ogiltiga värden, inkonsistenser, saknade främmande nycklar. Här är det viktigt att ur domänsynpunkt avgöra vad som är korrekt. Tekniskt bör applikationen framöver validera striktare och logga fel på ett spårbart sätt, istället för att tyst åtgärda dem.

Eftermontera gränssnitt utan att destabilisera legacysystemet

Många företag refaktorerar Delphi-bestånd eftersom nya krav tvingar fram integrationer: portaler, BI, mobila processer, partnerkopplingar. Det vanligaste misstaget är att mata gränssnitt direkt från UI-logik eller „någonstans ur koden“. Istället är det bättre att lägga gränssnitten på ett konsoliderat servicelager som byggs upp redan vid refaktoreringen.

När en REST-API (Representational State Transfer, vanlig webb-API över HTTP/JSON) eftermonteras är följande aspekter särskilt viktiga ur drift- och säkerhetssynpunkt:

  • AuthN/AuthZ: separera autentisering och auktorisation tydligt; t.ex. tokens, SAML 2.0 i samband med företags-SSO, tydliga rollmodeller.
  • Ratebegränsningar och timeouts: så att externa anrop inte blockerar backend.
  • Versionering: definiera API-versioner för att inte bryta klienter vid varje ändring.
  • Observability: strukturerade loggar, korrelations-ID:n, mätvärden (felkvoter, latens).

En intern länk till ett fördjupande inlägg om att eftermontera en REST-API för befintlig mjukvara kan här passa väl innehållsmässigt, eftersom gränssnitt i moderniseringsprojekt sällan är ett „tillägg“ utan ett eget driftsprodukt.

Säkerhet och compliance: refaktorering som tillfälle att täppa till säkerhetsbrister

Legacy betyder ofta att säkerhetsantaganden är äldre än dagens hotbild. Vid refaktorering bör ni åtminstone pröva om systemet behöver uppdateras på följande områden:

  • Credentials och Secrets: inga lösenord i INI-filer eller i koden; säker förvaring och rotation.
  • Transportkryptering: TLS för gränssnitt, ordnad certifikathantering.
  • Least Privilege: databas-användare och filrättigheter så minimala som möjligt; separata roller för läsning/skrivning/administration.
  • Revisionsspårbarhet: spårbara ändringar av kritiska data (Vem? Vad? När?), utan att loggdata skapar integritetsproblem.
  • För IT-ledningen är det en central affärsnytta: Refaktorisering minskar inte bara underhållskostnader utan kan också sänka säkerhets- och revisionsrisker om det genomförs strukturerat.

    Release- und Betriebsprozess: Ohne saubere Pipeline wird Refactoring teuer

    Många Delphi-legacyprojekt lider mer av processen än av koden: builds skiljer sig mellan arbetsplatser, releaser är manuella, fel kan inte spåras ordentligt. Refaktorisering bör därför också stabilisera leveransprocessen.

    Build-Reproduzierbarkeit und Konfigurationsmanagement

    Ur administrationens och revisionssynpunkt är det viktigt att en release är reproducerbar: samma källor, samma kompilator- och biblioteksversioner, samma beroenden. Det inkluderar tydligt separerade konfigurationer för utveckling, test och produktion (t.ex. databasendpunkter, loggnivåer, feature-flags).

    Logging, Monitoring und Supportfähigkeit

    „Det räcker inte att något har hänt“ i driften. Refaktorisering är ett bra tillfälle att införa enhetlig loggning: strukturerade loggposter, entydiga felkoder, kontext (user, tenant, uppdrag, gränssnitt) och tydlig åtskillnad mellan tekniska fel och fackliga/affärsmässiga valideringar.

    För 24/7-nära processer är följande dessutom lämpligt:

    • Hälsokontroller (t.ex. databasanslutning, köstockning, minnesanvändning),
    • Larmhantering efter allvarlighetsgrad,
    • Runbooks för återstart och typiska störningar.

    Ein praxistauglicher Refactoring-Fahrplan in 6 Schritten

    För att förhindra att refaktorisering går i stå i det dagliga arbetet hjälper en tydlig färdplan som är kompatibel med releasecykler. Ett beprövat tillvägagångssätt:

    1. Risk- och ändringskarta ta fram (moduler, gränssnitt, data, drift).
    2. Upprätta ett skyddsnät: loggningsstandard, inledande regression-/Golden-Master-tester för kritiska flöden.
    3. Dra upp arkitekturella skiljelinjer: tjänstelager och inkapsling av dataåtkomst som „ny norm“ för ändringar.
    4. Refaktorisera hotspots: de moduler som ofta ändras och orsakar avbrott (använd felstatistik och ändringshistorik).
    5. Konsolidera dataåtkomst: FireDAC/transaktioner/timeouter enhetliggörs, mät prestanda, granska deadlocks.
    6. Öppna moderniseringsvägar: gränssnitt (REST), plattformsfrågor (Unicode/64-Bit), successiv UI-modernisering där det är lämpligt.

    Kärnan är ordningsföljden: först transparens och säkring, sedan strukturåtgärder, därefter större ombyggnader. Så förblir lösningen leveransbar och driftstabil.

    Wann Refactoring nicht reicht: Signale für eine größere Modernisierung

    Det finns situationer där ren refaktorisering inte löser flaskhalsen. Typiska signaler:

    • Teknologiska återvändsgränder: databasdrivrutiner som inte längre stöds, komponenter som inte kan patchas, hårda 32-bitarsberoenden.
    • Arkitektur passar inte längre: t.ex. att applikationen måste köras som ett tjänstelandskap, men allt är UI-centrerat.
    • Skalning och tillgänglighet: krav på tenant-funktionalitet, hög tillgänglighet eller fjärråtkomst kan endast uppfyllas med strukturella förändringar.
    • Säkerhetskrav: autentisering/SSO, revisionsspårning, kryptering går inte att eftermontera utan större ombyggnad.

    Även då är refaktorisering ofta en meningsfull del: den skapar ordning för att målmedvetet kunna avgränsa delar istället för att ersätta hela systemet på en gång.

    Slutsats: Refaktorisering som tekniskt ansvar i löpande drift

    Att refaktorisera legacy-kod i Delphi är framför allt en fråga om prioritering, riskhantering och närhet till driften. Om ni börjar med en pålitlig inventering, säkrar hotspots, konsoliderar dataåtkomst och arkitekturgränser samt riktar tester och loggning mot kritiska flöden, blir „städning“ ett styrbart moderniseringsprojekt. Resultatet är inte bara mer läsbar kod, utan ett system som går att drifta mer tillförlitligt, ändra säkrare och integrera enklare.

    Om ni vill stabilisera eller modernisera er Delphi-befintliga lösning på ett strukturerat sätt, klargör vi gärna tillsammans utgångsläge, risker och en realistisk refaktoriseringsväg:

    I den tekniska kontexten spelar också Delphi Modernisering och Delphi refaktorisering en viktig roll när integrationer, dataflöden och vidareutveckling måste samverka på ett ordnat sätt.

    Diskutera projekt eller moderniseringsprojekt med Net-Base.

    nästa steg

    När ett ämne blir ett verkligt projekt bör arkitektur, befintligt bestånd och drift tidigt ses över gemensamt.

    Vi stöder inte bara vid enstaka frågor, utan även när kodsfragment, legacy-frågor eller portalidéer ska utvecklas till ett robust företagsprojekt.

    • Nuläge, målbild och tekniska risker bedöms tillsammans.
    • REST, dataåtkomst, portaler och utrullning skjuts inte upp som sena följder.
    • Ni ser tidigt vilken väg som är ekonomiskt och driftmässigt hållbar.

    Dela inlägg

    Dela det här inlägget direkt

    LinkedIn, X, XING, Facebook, WhatsApp och e-post är omedelbart tillgängliga. För Instagram förbereder vi länken och en kort text direkt.

    E-post

    Instagram öppnas i en ny flik. Länken och korttexten kopieras till urklipp först.