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 spänningsfältet: den går stabilt, speglar kärnprocesserna och är djupt integrerad med databaser, gränssnitt och arbetsflöden. Samtidigt ökar ändringsinsats och risk vid varje release, eftersom kompromisser, specialfall och beroenden har byggts upp över år. Det är här som Refaktorering av Legacy-kod i Delphi tar vid: inte som ett „Rewrite“-projekt, utan som en kontrollerad ombyggnad på ett system i drift – med mätbara effekter på underhållbarhet, release-säkerhet och drift.

I praktiken misslyckas refaktoreringsarbete sällan på grund av Delphi i sig, utan på grund av bristande transparens: Vad är affärskritiskt? Var ligger teknisk skuld (dvs. strukturella brister som fördyrar senare ändringar)? Vilka delar får hanteras inom underhållsfönster, vilka inte? Och hur förhindrar man att „städa upp“ skapar nya fel eller prestandaproblem i produktion? Detta inlägg beskriver ett praktiskt tillvägagångssätt som tar med IT-ledning och administration: från inventering över arkitektur- och datafrågor till tester, releaseprocess och säkerhetsfrågor.

Vad betyder „legacy“ i Delphi-projekt egentligen?

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

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

  • Tät koppling: UI, dataåtkomst och affärslogik är blandade; ändringar ger bieffekter.
  • Implizita regler: Affärslogik ligger i events, globala variabler eller databastriggers, 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: Exceptions tystas, meddelanden hamnar inte i central loggning.
  • Bygg- och release-fragilitet: beroenden, sökvägsproblem, olika kompilatorinställningar, manuella efterarbeten.
  • Brist på tester: kunskap sitter i huvuden eller i „klickförloppet“ hos erfarna användare.

Viktigt: Legacykod är inte automatiskt „dålig“. Ofta är den ett resultat av tidsbrist, teknologicykler och pragmatiska beslut. Refaktoring är då en investering i kontrollerbarhet – ur drift-, säkerhets-, compliance- och förändringstaktperspektiv.

Refaktoring vs. Rewrite: vad som ändras för drift och risk

En Rewrite (nyutveckling) lovar en ren start, men medför ofta långa parallella faser, nya typer av fel och höga migrationsrisker. Refaktoring syftar istället till inkrementell förbättring med 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:

  • Refaktoring: Strukturen förbättras, det externa beteendet ska förbli detsamma. Fokus: underhållbarhet, testbarhet, stabilitet, prestandareserver.
  • Omstrukturering/modernisering: ytterligare målmedvetna beteendeförändringar, t.ex. nya gränssnitt, ny databas, nya plattforms­mål.
  • Rewrite: ny kodbas, oftast ny UI/arkitektur; kräver migrering av data, processer, gränssnitt – ofta „Big Bang“ eller en lång övergångsfas.

För beslutsfattare är punkten central: Refaktorering är inte ett självändamål, utan ett verktyg för att minska Change-Risiken. Det är direkt driftrelevant när applikationen påverkar 24/7-processer, produktionsnära flöden eller kundnära portaler.

Refaktorera legacy-kod i Delphi: starta med en pålitlig nulägesbedömning

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

1) Kartlägg kritikalitet och driftsrealitet

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

Nyttiga 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 scheduler)?
  • 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 tekniska skulder ofta arkitektoniska: 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-analys är användbar:

  • Ofta ändrat & riskfyllt: högsta prioritet för refaktorering.
  • Ofta ändrat & låg risk: förbättra processer/tester, mindre strukturella åtgärder.
  • Sällan ändrat & riskfyllt: stabilisering/säkring (tester, logging), inte nödvändigtvis att „försköna“.
  • Sällan ändrat & låg risk: medvetet låta vara.

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

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-automation, Windows-services, schemalagda uppgifter, certifikat, proxykonfigurationer.

Här uppstår kostnader för refaktorering ofta indirekt: en „liten“ ändring kan kräva 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 åtgärdar dem målmedvetet

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

Monolitiska Forms: när användargränssnittet håller ihop systemet

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

Ett operativt beprövat sätt är att avlasta UI stegvis:

  • Use-Case-nära tjänster införa: verksamhetsoperationer som tydligt namngivna metoder istället för händelsekedjor.
  • Kapsla datatillgången: queries/transaktioner inte i UI-händelser, utan i dataåtkomstlager.
  • DTOs/Modeller (enkla dataobjekt) använda för att separera formulärets tillstånd från databastillstånd.

Målet är inte „pattern-renhet“, utan bättre testbarhet och färre sidoeffekter: en ändring i validering eller beräkning ska inte äventyra hela UI-klicksekvensen.

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

Om BDE eller oenhetliga datakomponenter fortfarande används är refaktorisering ofta samtidigt en modernisering av driftspotentialen. BDE är inte bara gammalt utan ofta svårt att drifta: drivrutiner, konfiguration, 32-bit-beroenden och saknade moderna säkerhetsmekanismer.

BDE-ersättning med native-anslutning (Delphis moderna dataåtkomstbibliotek) är i många scenarier en rimlig standard, om arbetet är konsekvent: enhetliga anslutningsparametrar, tydliga transaktionsgränser, timeouter, poolning och ren undantagshantering. Typiska refaktoreringsåtgärder inom detta område:

  • Enhetliggör anslutningshanteringen: central Factory/Provider istället för „varje formulär har sin Connection“.
  • Gör transaktioner explicita: Begin/Commit/Rollback som del av use-case, inte dolda i UI.
  • Parametriserade Queries använda konsekvent för att minska SQL-Injection-risker och problem med specialtecken.
  • Definiera Timeouts och Retries, så att hängningar i nätverket inte leder till „frusna“ formulär.

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

Unit-beroenden och „globala tillstånd“ som huvudorsak till sidoeffekter

Delphi-Units med stora interface-sektioner, många Uses-poster och globala Singletons är typiska acceleratorer för sidoeffekter. En liten ändring i en Unit drar med sig rebuild-kaskader eller bryter dolda initialiseringssekvenser.

Pragmatiska åtgärder 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 livstid och ägarskap.

Det bidrar till stabilitet: om uppstarten är deterministisk är fel efter uppdateringar eller konfigurationsändringar bättre hanterbara.

Trådning och synkronisering: stabilitet före „Performance-Optimierung“

Många legacy-applikationer blir med tiden samtidiga: bakgrundsimporter, polling, kommunikation med enheter, parallell bearbetning. Utan tydliga regler uppstår deadlocks, UI-hängningar eller race conditions (åtkomstkonflikter vid samtidig exekvering).

För drift och support är detta ett problem eftersom det ofta ger upphov till ‚icke reproducerbara‘ fel. Refaktorering bör här syfta till standarder:

  • Tydligt ägarskap för Threads/Tasks och definierad nedstängning (så att uppdateringar/avslut inte fastnar).
  • Loggning per Worker med Korrelations-ID, för att spåra flöden.
  • Minimera synkronisering och kapsla strikt UI-åtkomst (UI-Thread-Regel).

Om ni vill fördjupa er i detta kan en intern länk till ett inlägg om robusta mönster med TThread och Synchronize placeras lämpligt, eftersom ämnet vid legacy-refaktorering ofta är flaskhalsen för stabilitet.

Målbild för arkitektur: Layering som verktyg, inte dogma

En praktisk 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 driftsperspektivet: Layering underlättar tester, uppdateringar och senare avkoppling av gränssnitt.

Konkreta fördelar för företag:

  • Eftermontera 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 isoleras snabbare eftersom ansvarsområden i koden är tydligare.

En realistisk målbild tar hänsyn till att legacy-system sällan blir ‚rena‘. Det avgörande är att riktningen är korrekt och att nya ändringar inte luckrar upp strukturen igen.

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

Refaktorering 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 målinriktat 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 nuvarande beteende: indata 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-tester minskar risken att sidoeffekter först visar sig 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, teckenkodning (t.ex. Unicode), tidsstämplar, decimaltecken, rättigheter, nätverksstörningar. Integrationstester bör därför åtminstone täcka följande punkter:

  • Transaktionsbeteende vid fel (Rollback, deluppdateringar, låsningar).
  • Teckenkodning 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 är kopplade till releaser. Ur administrationssynpunkt är det relevant att testfallen även innehåller driftsaspekter: installations-/uppdateringsväg, rättigheter, konfiguration, logging/övervakning, skrivare/PDF, nätverksvägar.

Data och migration: Refaktorering avgörs ofta utifrån schemat

I Delphi-system har databasstrukturer växt över många år. Refaktorering kolliderar ofta med „historiska“ tabeller, duplicerade fält eller funktionellt överbelastade kolumner. Den kritiska punkten: schemaändringar påverkar drift, säkerhetskopiering/återställning, replikering, rapportering och gränssnitt.

Gör schemaändringar planbara

Ett beprövat tillvägagångssätt är tydligt versionerade databasmigrationer: varje ändring av schemat dokumenteras som ett reproducerbart steg, inklusive en återställningsstrategi. Även om migrationer initialt utförs manuellt är disciplinen avgörande: inga „vi ändrar snabbt i produktion“.

För release-säkerhet bör ni fastställa:

  • Behov av driftstopp: Är online-migration möjlig eller krävs ett underhållsfönster?
  • Återställningsstrategi: Datakompatibilitet vid återställning, säkerhetskopior 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, inkonsekvenser, saknade främmande nycklar. Här är det viktigt att fackmässigt avgöra vad som är korrekt. Tekniskt bör applikationen i framtiden validera tydligare och logga fel spårbart, istället för att tyst korrigera.

Eftermontera gränssnitt utan att destabilisera legacysystemet

Många företag refaktoriserar 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 i koden“. Bättre är att placera gränssnitten i ett konsoliderat servicelager som byggs upp redan under refaktoreringen.

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

  • AuthN/AuthZ: Ren separation mellan autentisering och auktorisation; t.ex. tokens, SAML 2.0 i samband med företags-SSO, tydliga rollmodeller.
  • Rate Limits och Timeouts: så att externa anropare 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, latenser).

En intern länk till ett fördjupande inlägg om att eftermontera en REST-API för befintlig programvara passar väl här, eftersom gränssnitt i moderniseringsprojekt sällan är ett „add-on“ utan ett eget driftsansvar.

Säkerhet och efterlevnad: refaktorering som en möjlighet att åtgärda säkerhetsbrister

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

  • Credentials och Secrets: inga lösenord i INI‑filer eller i koden; säker lagring och rotation.
  • Transportkryptering: TLS för gränssnitt, korrekt certifikathantering.
  • Principen om minsta möjliga behörighet: databas‑användare och filrättigheter så minimala som möjligt; separata roller för läsning/skrivning/administration.
  • Revisionsbarhet: spårbara förändringar av kritiska data (Vem? Vad? När?), utan att göra loggdata till ett dataskyddsproblem.
  • För IT-ledning är detta en central affärsnytta: refaktorering minskar inte bara underhållskostnader utan kan också sänka säkerhets- och revisionsrisker om den genomförs strukturerat.

    Release- och driftsprocess: Utan en stabil pipeline blir refaktorering dyrt

    Många Delphi-legacy-projekt lider mindre av koden än av processen: builds skiljer sig mellan arbetsstationer, releaser är manuella, fel kan inte spåras ordentligt. Refaktorering bör därför även stabilisera leveransprocessen.

    Build-reproducerbarhet och konfigurationshantering

    Ur administrations- och revisionssynpunkt är det viktigt att en release är reproducerbar: samma källor, samma compiler-/biblioteksversioner, samma beroenden. Dit hör tydligt åtskilda konfigurationer för utveckling, test och produktion (t.ex. databasendpoints, loggningsnivåer, feature-flaggor).

    Loggning, övervakning och supportbarhet

    „Något hände“ räcker inte i drift. Refaktorering är ett bra tillfälle att införa enhetlig loggning: strukturerade loggposter, entydiga felkoder, kontext (användare, kund, ärende, gränssnitt) och en tydlig separation mellan tekniska fel och verksamhetsvalideringar.

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

    • Health Checks (t.ex. databasanslutning, köstockning, minnesförbrukning),
    • Larmhantering efter allvarlighetsgrad,
    • Runbooks för återstart och typiska fel.

    En praktisk färdplan för refaktorering i 6 steg

    För att refaktorering inte ska fastna i det dagliga arbetet hjälper en tydlig färdplan som är kompatibel med releasecykler. Ett beprövat förhållningssätt:

    1. Skapa en risk- och förändringskarta (moduler, gränssnitt, data, drift).
    2. Spänna ett skyddsnät: loggningsstandard, initiala regressions-/Golden-Master-tester för kritiska flöden.
    3. Dra arkitekturgränser: servicelagret och kapsling av dataåtkomst som „ny normal“ för ändringar.
    4. Refaktorera hotspots: de moduler som ofta ändras och orsakar avbrott (använd felstatistik och ändringshistorik).
    5. Konsolidera dataåtkomst: FireDAC/transaktioner/timeouter standardiseras, mät prestanda, kontrollera deadlocks.
    6. Öppna moderniseringsvägar: gränssnitt (REST), plattformsfrågor (Unicode/64-Bit), stegvis UI-modernisering där det är motiverat.

    Kärnan är ordningen: först transparens och säkringar, sedan strukturåtgärder, därefter större ombyggnader. På så vis förblir lösningen leveransbar och driftstabil.

    När refaktorering inte räcker: signaler för en större modernisering

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

    • Teknologiska återvändsgränder: databasdrivrutiner som inte längre stöds, komponenter som inte går att patcha, hårda 32-bitarsberoenden.
    • Arkitekturen passar inte längre: t.ex. applikationen måste drivas som ett servicelandskap, men allt är UI-centrerat.
    • Skalning och tillgänglighet: krav på multitenancy, hög tillgänglighet eller fjärråtkomst kan endast uppfyllas med strukturella ändringar.
    • Säkerhetskrav: autentisering/SSO, revision, kryptering kan inte eftermonteras utan större ombyggnad.

    Även då är refaktorering ofta en meningsfull komponent: den skapar ordning för att målmedvetet frikoppla delar istället för att ersätta hela systemet på en gång.

    Slutsats: Refaktorering som tekniskt ansvar i löpande drift

    Att refaktorera legacykod i Delphi är framför allt en fråga om prioritering, riskhantering och driftnära perspektiv. Om ni börjar med en tillförlitlig nulägesanalys, säkrar hotspots, konsoliderar dataåtkomst och arkitekturens avgränsningar samt riktar tester och loggning mot kritiska flöden, blir „städa upp“ ett styrbart moderniseringsprojekt. Resultatet är inte bara mer läsbar kod utan ett system som är lättare att drifta pålitligt, säkrare att förändra och enklare att integrera.

    Om ni vill strukturera och stabilisera eller modernisera er Delphi-beståndslösning, klargör vi gärna tillsammans utgångsläge, risker och en realistisk refaktoreringsväg:

    I det professionella sammanhanget spelar också Delphi modernisering och Delphi refaktorering en viktig roll när integrationer, dataflöden och vidareutveckling måste samspela väl.

    Diskutera projekt eller moderniseringsprojekt med Net-Base.

    Nächster Schritt

    Wenn aus dem Thema ein reales Projekt wird, sollten Architektur, Bestand und Betrieb früh zusammen betrachtet werden.

    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, Datenzugriff, Portale und Rollout werden nicht als Spätfolgen verschoben.
    • Sie sehen früh, welcher Weg wirtschaftlich und betrieblich tragfähig ist.

    Dela inlägg

    Dela det här inlägget direkt

    LinkedIn, X, XING, Facebook, WhatsApp und E-Mail sind sofort verfügbar. Für Instagram bereiten wir Link und Kurztext direkt vor.

    E-post

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