Teknisk resumé
Vigtigste pointer:

Artiklen påpeger, at refaktorering af en industriel applikation giver mening, når omkostningerne ved og usikkerheden omkring mindre ændringer stiger hurtigere end deres forretningsmæssige værdi. Det afgørende er at skelne mellem oprydning i strukturen og en teknisk ændring, der påvirker processen eller sikkerheden.

  • Refaktorering af en ældre applikation handler om produktionskontinuitet, omkostninger og ansvar – ikke kun om kodekvalitet.
  • Risikoen øges, når ændringen påvirker signaler, tilstande, handlingsrækkefølgen eller procesens overgangsbetingelser.
  • Tilsyneladende tekniske ændringer kan ændre start, stop, nulstilling af fejl, reaktionen ved strømsvigt og tab af forbindelse.
  • Hvis sekvenserne eller beskyttelseskredsenes reaktioner skal verificeres igen, er det ikke længere almindelig kodevedligeholdelse.
  • Sikker refaktorering kræver fastlæggelse af ændringens afgrænsning, acceptkriterier og en risikovurdering af processen.

Hvorfor emnet er vigtigt i dag

Refaktorering af en ældre industriel applikation er ikke længere et spørgsmål om kodens æstetik eller om, hvor let den er at vedligeholde. I dag er det en beslutning, der handler om produktionskontinuitet, forudsigelige omkostninger og omfanget af systemejerens ansvar. I mange virksomheder er styringsapplikationer, operatørværktøjer og kommunikationslag blevet udviklet gennem mange år uden en samlet arkitektur, ofte omkring udstyr, biblioteker og integrationsmekanismer med begrænset eller ophørt support. En sådan situation kan i en periode være acceptabel, men kun indtil hver næste ændring begynder at koste mere end den funktionalitet, den skal levere. På det tidspunkt er spørgsmålet ikke længere, om man skal røre den gamle applikation, men om organisationen stadig har kontrol over dens adfærd under produktionsforhold.

Emnets betydning skyldes, at teknisk gæld i industrielle systemer meget hurtigt bliver til driftsmæssig gæld. Hvis applikationen er vanskelig at genskabe, afhænger af enkeltpersoner, mangler pålidelige regressionstests, eller hvis dens logik blander produktionsfunktioner med funktioner knyttet til sikkerhed og diagnostik, vil enhver hændelse blive dyrere end et tilsvarende problem i et kontorsystem. Konsekvensen er ikke kun nedetid. Dertil kommer vedligeholdelsesomkostninger, risikoen for fejlagtige nødrettelser under tidspres, problemer med at dokumentere rettidig omhu efter ændringen samt vanskeligheden ved at skelne mellem, hvad der var en eksisterende fejl, og hvad der er en følge af projektteamets indgreb. For en leder og en produktejer er det praktiske kriterium enkelt: Hvis tiden og usikkerheden ved implementering af selv små ændringer vokser hurtigere end deres forretningsmæssige værdi, har applikationen nået et punkt, hvor beslutningen om refaktorering skal træffes bevidst og ikke udsættes til den første kritiske fejl.

De fleste fejl opstår, når refaktorering behandles som en modernisering “uden påvirkning af processen”, selv om den i praksis ændrer den måde, systemet træffer beslutninger på. I praksis er et tilsyneladende lille indgreb nok: udskiftning af en kommunikationskomponent, ombygning af opgaveplanlægningen, ændring af logikken for buffering af sensordata eller oprydning i opstartssekvensen efter genstart. På papiret er det tekniske justeringer. På fabriksgulvet kan de derimod ændre tidspunktet for et signal, rækkefølgen for frigivelse af spærringer, reaktionen ved tab af forbindelse eller applikationens adfærd efter strømsvigt. Det er netop her, refaktorering bliver til en praktisk vurdering af ændringsrisikoen: Det afgørende er ikke, om koden er “bedre”, men om maskinen, linjen eller arbejdsstationen efter ændringen stadig opfører sig forudsigeligt i normal drift, ved forstyrrelser og efter genstart.

En god test af, om beslutningen er moden, er at undersøge, om teamet kan fastlægge grænsen mellem en ændring i applikationens interne struktur og en ændring i en funktion, der er væsentlig for processen eller sikkerheden. Hvis denne grænse ikke kan beskrives på niveau med signaler, tilstande og overgangsbetingelser, er projektet forbundet med risiko uanset leverandørens kvalitet. I industrielle miljøer er situationer særligt følsomme, når applikationen indgår i sekvensen for start, stop, fejlreset, alarmkvittering eller samarbejder med systemer til energiafbrydelse og spærringer. På dette tidspunkt opstår ikke kun spørgsmålet om softwarearkitektur, men også om sikring mod utilsigtet opstart og om analysen også omfatter den elektriske installation, styrelogikken og afhængighederne mellem enhederne. Det er netop her, hvor en tilsyneladende lokal refaktorering ophører med at være en IT-opgave og bliver en teknisk ændring, der kræver fuld beslutningsmæssig styring.

Henvisningen til normative krav bliver først relevant på dette trin, fordi standarder ikke erstatter en projekteringsbeslutning, men afgrænser dens omfang. Hvis ændringen kan påvirke betingelserne for opstart, stop, genoptagelse af drift efter en forstyrrelse eller beskyttelsesforanstaltninger, skal den vurderes som en risikoændring og ikke som almindelig vedligeholdelse af kode. Hvis indgrebet berører logik, der samarbejder med energiafbrydelse, spærringer eller sekvensen for sikker adgang, åbner det naturligt også området for krav vedrørende sikring mod utilsigtet opstart. Set ud fra et ansvarsperspektiv er det derfor vigtigste ikke blot “om man skal refaktorere”, men om organisationen kan dokumentere, at den kender ændringens grænser, har acceptkriterier baseret på procesadfærd og kan skelne mellem systemoprydning og en ændring, der kræver en fuld vurdering af ændringsrisikoen i henhold til ISO 12100 samt koordinering med projektering af installationen og test på anlægget.

Hvor vokser omkostningerne eller risikoen oftest

Den største omkostningsstigning ved refaktorering af en ældre industriel applikation skyldes sjældent selve koden. Problemet opstår som regel, fordi ændringen klassificeres forkert: teamet behandler den som en oprydning i programmets struktur, selv om der i praksis ændres på anlæggets tidsmæssige adfærd, rækkefølgen af handlinger eller betingelserne for overgang mellem tilstande. I et produktionsmiljø har en sådan fejlklassificering en direkte projektmæssig konsekvens. Tidsplanen holder op med at svare til det reelle omfang, testene planlægges ud fra it-funktionalitet frem for procesforløb, og ansvaret for resultatet flyder ud mellem vedligehold, automation og softwareleverandøren. Det praktiske kriterium er her enkelt: Hvis ændringen kræver, at man på ny bekræfter sekvensen for opstart, stop, genoptagelse efter en forstyrrelse eller reaktionen på signaler fra beskyttelseskredse, er der organisatorisk set ikke længere tale om “sikker refaktorering”, men om en ændring, der kan skabe risiko for produktionen og kræver en anden godkendelsesproces.

Et andet typisk område, hvor omkostningerne vokser, er en projekteringsbeslutning truffet uden et fuldt billede af afhængighederne. Ældre industrielle applikationer er ofte tæt vævet sammen med PLC-konfiguration, aktuatorer, visualisering, dataarkivering og operatørprocedurer. I dokumentationen ser det ud som ét system, men i praksis er det lag, der er blevet udviklet gennem mange år af forskellige teams. En refaktorering, der skal forbedre kodens læsbarhed eller lette den videre vedligeholdelse, kan ubemærket ændre betydningen af forsinkelser, spærringsbetingelser, standardværdier efter genstart eller måden, en kommunikationsfejl håndteres på. Konsekvensen er ikke kun en teknisk rettelse, men også omkostninger til nedetid, ekstra afprøvninger på anlægget og diskussioner om, hvorvidt fejlen fandtes i forvejen eller blev indført med ændringen. Derfor bør man før beslutningen ikke kun vurdere ændringens størrelse, men også antallet og kritikaliteten af grænsefladerne: hvor mange signaler, recepter, driftstilstande og driftsmæssige workarounds der afhænger af den del af koden, som skal bygges om. Jo flere sådanne berøringspunkter der er, desto mindre mening giver det at refaktorere “ved siden af” en anden opgave.

I praksis er de dyreste projekter ofte dem, hvor teamet først opdager de reelle krav under idriftsættelsen. Et typisk eksempel er ombygning af et sekvensmodul, som ifølge beskrivelsen “gør det samme, bare mere rent”. Efter implementeringen viser det sig imidlertid, at den tidligere version indeholdt udokumenterede adfærdsmønstre, som kompenserede for anlæggets ufuldkommenheder: et kort signalhold, tolerance over for en forsinket sensor, en bestemt rækkefølge for kvittering af alarm eller en betingelse, som afgør, om serviceadgang er mulig. I koden så det ud som en fejl eller teknisk gæld, men for processen var det et stabiliserende element. Hvis refaktoreringen fjerner sådanne mekanismer uden at afklare deres funktion, opstår omkostningen med det samme: antallet af indgreb efter idriftsættelse stiger, overtagelsesfasen trækker ud, og logikken må genskabes under pres fra den kørende drift. Derfor bør værdien af en refaktorering også vurderes ud fra muligheden for at genskabe det nuværende systems adfærd. Hvis organisationen ikke har hændelsesregistrering, troværdige beskrivelser af driftstilstande og testscenarier baseret på den faktiske proces, skal man først etablere grundlaget for vurderingen og først derefter træffe beslutning om ombygning.

Dette leder direkte over i en praktisk vurdering af risikoen ved ændringen i henhold til ISO 12100, når modifikationen påvirker beskyttelsesfunktioner, sekvenser for sikker adgang, styring af bevægelsen i aktuatorer eller anlæggets adfærd ved strømsvigt og efter spændingen vender tilbage. I et sådant omfang er omkostningen ved en fejl ikke begrænset til programmeringsrettelser, fordi spørgsmålet om ansvar for at frigive ændringen til drift også opstår. Hvis applikationen arbejder sammen med hydrauliske eller pneumatiske systemer eller løsninger som tohåndsbetjening, bliver grænsen mellem refaktorering og teknisk ændring endnu snævrere, og det kræver kontrol af, om de projekteringsmæssige forudsætninger for beskyttelsesforanstaltningerne er blevet påvirket. Først her er det relevant at henvise til systematiske metoder til risikovurdering, herunder den tilgang, der i praksis anvendes på grundlag af ISO/TR 14121-2, og ved hydrauliske systemer også til de projekteringskrav, der er struktureret i DS/EN ISO 4413. Det handler ikke om formalisme for formalismens egen skyld, men om et enkelt beslutningsprincip: Hvis ændringen kan påvirke proces- eller driftssikkerheden, skal dens omkostning beregnes sammen med validering, test på anlægget og ansvarsregimet – ikke kun ud fra programmørens arbejdstid.

Hvordan griber man emnet an i praksis

I praksis vurderes værdien af at refaktorere en ældre industriel applikation ikke ud fra, hvor teknologisk attraktiv ændringen er, men ud fra om man samtidig kan reducere driftsrisikoen og bevare kontrollen over implementeringen. For en leder og en produktejer betyder det et enkelt skift i perspektiv: spørgsmålet er ikke, om koden “bør ryddes op”, men om applikationens nuværende tilstand reelt gør vedligeholdelse, test, fejlretning eller kravmæssigt korrekte ændringer vanskeligere. Hvis svaret er ja, giver refaktorering mening, men kun i et omfang, der kan holdes adskilt fra produktionen og vurderes på baggrund af målbare effekter. Et godt beslutningskriterium er her at sammenligne to omkostninger: omkostningen ved at lade applikationen forblive i sin nuværende tilstand, herunder stop, fejlsøgningstid, afhængighed af enkeltpersoner og risikoen for fejlbehæftede ændringer, og omkostningen ved en kontrolleret ombygning med test, validering og idriftsættelse. Uden en sådan sammenligning løber projektet som regel af sporet, fordi teamet finansierer oprydning i koden med et budget, der var afsat til funktionalitet, mens ansvaret for konsekvenserne på anlægget forbliver uafklaret.

Derfor bør den første beslutning ikke være “vi omskriver” eller “vi lader det være”, men at fastlægge ændringens grænse. I en moden tilgang skelner man mellem den del, der udelukkende vedrører softwarestrukturen, og den del, der påvirker proceslogikken, start- og stopsekvenser, driftstilstande, kommunikation med drev og adfærden efter strømsvigt. Denne sondring har direkte betydning for både omkostninger og organisering. En ændring, der er begrænset til et lag, som alene strukturerer koden, kan gennemføres i en kortere cyklus og med mindre involvering fra vedligeholdelsesfunktionen. En ændring, der påvirker maskinens eller linjens adfærd, kræver derimod en testplan på anlægget, et servicevindue, en rollback-procedure og en entydig afklaring af, hvem der godkender frigivelsen til drift. Det er samtidig værd at måle ikke kun tiden til selve programmeringsarbejdet, men også tiden til at gendanne systemet efter et mislykket forsøg, antallet af områder omfattet af regressionstest og den tid, der kræves for at diagnosticere en afvigelse efter idriftsættelse. Det er indikatorer, som viser, om refaktoreringen faktisk reducerer projektrisikoen, og ikke blot forbedrer komforten for udviklingsteamet.

Et praktisk eksempel er typisk for ældre styreapplikationer: koden indeholder mange gentagne sektioner, der håndterer bevægelsesblokeringer, alarmhåndtering og skift mellem manuel og automatisk drift. Teamet ønsker at ensrette dem, fordi den nuværende struktur gør videreudvikling vanskelig og skaber forskelle mellem stationer. En sådan beslutning giver først mening, når det er verificeret, at ensretningen ikke ændrer de betingelser, hvorunder et aktuatorelement får tilladelse til bevægelse, og at der efter genstart af controlleren ikke opstår en anden sekvens for gendannelse af tilstanden. Hvis applikationen også styrer ventiler, drev eller systemer med lagret energi, kan selv en tilsyneladende “intern” refaktorering bevæge sig over i området for vurdering af ændringsrisiko efter ISO 12100 og kræve analyse af beskyttelsen mod utilsigtet opstart. I sådanne tilfælde er en fornuftig praksis at gennemføre refaktoreringen trinvis: først genskabe adfærden i et testmiljø, derefter udskille moduler uden at ændre logikken og derefter verificere på anlægget med et forberedt rollback-scenarie. Det begrænser det driftsmæssige ansvar og gør det muligt at stoppe implementeringen, før problemet påvirker produktionen.

Først på dette trin er en normativ reference nødvendig, for standarder kan ikke erstatte en teknisk beslutning, men de hjælper med at fastlægge det tidspunkt, hvor ændringen ikke længere kun er programmeringsarbejde. Hvis refaktoreringen påvirker beskyttelsesforanstaltninger, betingelser for sikker adgang, afbrydelse af energi eller systemernes adfærd efter stop og genstart, falder den naturligt ind under en praktisk og systematisk vurdering af ændringsrisikoen, også med brug af den tilgang, der kendes fra ISO/TR 14121-2. Når der opstår risiko for utilsigtet opstart, skal man ikke kun kontrollere selve koden, men også logikken for afbrydelse og genetablering af energi, hvilket leder direkte til emner forbundet med ISO 14118. Hvis applikationen desuden er koblet til hydraulik eller pneumatik, må vurderingen ikke se bort fra disse systemers designforudsætninger, fordi en forkert styresekvens kan kompromittere deres sikre funktion uanset, om selve programmet er korrekt; i så fald er det også relevant at inddrage de krav, der strukturerer projektering af hydrauliske systemer. I praksis betyder det én ting: omfanget af refaktoreringen afgøres ikke af løsningens elegance, men af grænsen for ansvaret for anlæggets sikre adfærd efter ændringen.

Hvad man skal være opmærksom på ved implementering

Implementering af refaktorering i en ældre industriel applikation er det tidspunkt, hvor selv en korrekt arkitektonisk beslutning kan udvikle sig til et driftsproblem. Hele initiativets værdi ophører dér, hvor ændringen forbedrer koden, men forringer anlæggets forudsigelighed i drift eller udvider teamets ansvar ud over det, der er identificeret og godkendt. Den mest almindelige fejl er at behandle implementeringen som en almindelig publicering af en ny version. I et produktionsmiljø er det ikke nok, at applikationen fungerer; det afgørende er også, om alle overgangstilstande opfører sig identisk efter ændringen: opstart efter strømsvigt, genstart af kommunikation, gendannelse af recepter samt håndtering af alarmer, blokeringer og manuelle tilstande. Det praktiske kriterium er enkelt: Hvis teamet ikke entydigt kan beskrive, hvilke adfærdsmønstre der skal forblive uændrede efter implementeringen, er betingelserne for sikker idriftsættelse endnu ikke til stede.

I beslutningsfasen for implementeringen skal man skelne mellem en teknisk reversibel ændring og en ændring, som efter idriftsættelse etablerer en ny baseline og gør det vanskeligere at rulle tilbage. Det har direkte konsekvenser for både omkostninger og tidsplan. En refaktorering, der kræver samtidig opdatering af drivere, visualisering, dataserver og grænseflader til overordnede systemer, er ikke længere en enkeltstående programmeringsopgave; den bliver til en koordineret produktionsændring med flere mulige fejlpunkter. Derfor bør man før implementering fastlægge et godkendelseskriterium, der ikke bygger på erklæringen “testene er bestået”, men på evnen til at tilbageføre ændringen kontrolleret inden for en tid, som processen kan acceptere. Hvis der ikke findes en troværdig rollback-procedure, er der heller ikke grundlag for at hævde, at risikoen er under kontrol. I praksis er det mere nyttigt at måle ikke en abstrakt “implementeringskvalitet”, men indikatorer som tiden til gendannelse af den tidligere version, antallet af grænseflader, der afhænger af ændringen, samt antallet af funktioner, hvis korrekthed kan bekræftes på anlægget uden indgreb i produktionen.

Et godt eksempel er en situation, hvor refaktoreringen rydder op i håndteringen af undtagelser og fejlmeddelelser, men samtidig ændrer rækkefølgen af initialiseringen efter genstart af systemet. På testopstillingen ser alt korrekt ud, fordi enhederne er tilgængelige med det samme, og processen ikke kører under belastning. I anlægget kan den samme kode imidlertid starte sekvensen på et andet tidspunkt end hidtil, hvilket fører til tab af synkronisering med drev, fejlagtig fortolkning af klar-signaler eller stop af en materialebatch i en mellemtilstand. En sådan hændelse behøver ikke at være en teknisk fejl i snæver forstand, men den medfører omkostninger til stilstand, kassation, genopstart og et ekstra ansvar i forbindelse med beslutningen om at genoptage driften. Det er netop her, refaktorering glider over i en praktisk vurdering af ændringsrisiko: ikke når ændringen er stor, men når dens konsekvenser ikke kan begrænses til softwarelaget.

Ansvarsgrænsen bliver endnu tydeligere dér, hvor applikationen påvirker beskyttelsesfunktioner, logik for frigivelse af bevægelse, aflastningssekvenser, stop og genstart efter en forstyrrelse. I sådanne tilfælde er det ikke længere tilstrækkeligt at sammenligne kodeversioner eller udføre en funktionstest hos integratoren. Der er behov for en systematisk vurdering af, om ændringen modificerer risikoniveauet, og om den ikke bryder med forudsætningerne for sikker drift af maskinen eller anlægget. Det er et naturligt tidspunkt at gå ind i området for risikovurdering efter ISO 12100 samt de praksisser, der anvendes ved vurdering af ændringsrisici, og i mere komplekse tilfælde kan en metodisk tilgang kendt fra ISO/TR 14121-2 være nyttig. Hvis applikationen styrer hydrauliske eller pneumatiske systemer, skal man desuden kontrollere, om den nye logik ændrer betingelserne for sikker styring af energi og bevægelsesrækkefølge; her er det også de projekteringskrav, der gælder for disse systemer, som er afgørende, ikke kun selve programmets korrekthed. For projektteamet betyder det én ting: En implementering kan først anses for at være forberedt, når omfanget af det tekniske, driftsmæssige og compliance-relaterede ansvar er defineret før idriftsættelsen og ikke først efter den første hændelse.

Refaktorering af en ældre industriel applikation – hvornår giver det mening, og hvordan gør man det uden risiko for produktionen?

Det giver mening, når omkostningerne og usikkerheden ved at implementere mindre ændringer vokser hurtigere end deres forretningsmæssige værdi. Det er et signal om, at den tekniske gæld er begyndt at påvirke produktionskontinuiteten og driftsomkostningerne.

Når ændringen påvirker signaler, tilstande, overgangsbetingelser eller sekvenser for start, stop og genoptagelse af driften. Så er det ikke længere kun et spørgsmål om arkitektur, men en teknisk ændring, der kræver en risikovurdering.

Oftest dér, hvor systemets adfærd ændrer sig over tid: opgaveplanlægning, rækkefølgen af handlinger, bufferlogik, reaktion ved tab af forbindelse eller ved strømsvigt. Selv et mindre indgreb kan da ændre forudsigeligheden i maskinens eller linjens drift.

Der skal trækkes en klar grænse mellem ændringer i applikationens struktur og ændringer i en funktion, der er væsentlig for processen eller sikkerheden. Acceptkriterierne bør baseres på procesadfærden, og testene bør også omfatte normaltilstande, fejlsituationer og genstart.

Når indgrebet vedrører logik forbundet med start, stop, fejlnulstilling, spærringer, afbrydelse af energi eller sikker adgang. I sådanne tilfælde skal ændringen betragtes som en ændring af risikoen og ikke som almindelig vedligeholdelse af koden.

Del: LinkedIn Facebook