Pagrindinės įžvalgos:
Straipsnyje nurodoma, kad pramoninės taikomosios programos refaktorizavimas yra prasmingas tada, kai nedidelių pakeitimų sąnaudos ir neapibrėžtumas auga greičiau nei jų verslo vertė. Svarbiausia atskirti struktūros tvarkymą nuo techninio pakeitimo, darančio įtaką procesui ar saugai.
- Senos programos refaktorizavimas susijęs su gamybos tęstinumu, sąnaudomis ir atsakomybe, o ne vien tik su kodo kokybe.
- Rizika didėja, kai pakeitimas turi įtakos signalams, būsenoms, veiksmų sekai arba proceso perėjimo sąlygoms.
- Iš pažiūros techniniai pakeitimai gali pakeisti paleidimą, sustabdymą, klaidų atstatymą, reakciją į maitinimo dingimą ir ryšio praradimą.
- Jei reikia iš naujo patvirtinti apsauginių grandinių sekas ar reakcijas, tai jau nėra vien tik įprasta kodo priežiūra.
- Saugiam perprojektavimui reikia nustatyti pakeitimo ribas, priėmimo kriterijus ir proceso rizikos vertinimą.
Kodėl ši tema šiandien svarbi
Senos pramoninės programos refaktorizavimas jau nebėra vien kodo estetikos ar priežiūros patogumo klausimas. Šiandien tai sprendimas, susijęs su gamybos tęstinumu, sąnaudų nuspėjamumu ir sistemos savininko atsakomybės apimtimi. Daugelyje įmonių valdymo programos, operatorių įrankiai ir komunikacijos sluoksniai buvo kuriami metų metus, neturint vieningos architektūros, dažnai remiantis įrenginiais, bibliotekomis ir integracijos mechanizmais, kurių palaikymas yra ribotas arba jau nutrauktas. Kurį laiką tokia padėtis gali būti toleruojama, tačiau tik iki momento, kai kiekvienas kitas pakeitimas ima kainuoti daugiau nei pati funkcija, kurią jis turi suteikti. Tuomet klausimas jau nebe tas, ar verta imtis senos programos, o ar organizacija vis dar kontroliuoja jos elgseną gamybos sąlygomis.
Šios temos svarba kyla iš to, kad pramoninėse sistemose technologinė skola labai greitai virsta operacine skola. Jeigu programą sunku atkurti, ji priklauso nuo pavienių žmonių, nėra patikimų atkuriamųjų testų arba jos logikoje susipina gamybinės funkcijos su saugos ir diagnostikos funkcijomis, kiekvienas incidentas kainuos daugiau nei panaši problema biuro sistemoje. Pasekmė nėra vien tik prastova. Prisideda techninės priežiūros darbo sąnaudos, klaidingų laikinų sprendimų rizika, taikomų dėl laiko spaudimo, sunkumai įrodant deramą rūpestingumą po pakeitimo ir keblumas atskirti, kas buvo ankstesnis gedimas, o kas – projektavimo komandos įsikišimo pasekmė. Vadovui ir produkto savininkui praktinis kriterijus paprastas: jeigu laikas ir neapibrėžtumas diegiant tolesnius smulkius pakeitimus auga greičiau nei jų verslo vertė, programa pasiekė būseną, kai sprendimą dėl refaktorizavimo reikia priimti sąmoningai, o ne atidėlioti iki pirmojo kritinio gedimo.
Daugiausia klaidų atsiranda tada, kai refaktorizavimas traktuojamas kaip modernizavimas „be poveikio procesui“, nors iš tikrųjų jis pakeičia tai, kaip sistema priima sprendimus. Praktikoje pakanka iš pažiūros nedidelio įsikišimo: pakeisti komunikacijos komponentą, pertvarkyti užduočių tvarkaraštį, pakeisti jutiklių duomenų buferiavimo logiką arba sutvarkyti paleidimo seką po perkrovimo. Dokumentuose tai atrodo kaip techniniai tvarkymo darbai. Tačiau ceche tai gali pakeisti signalo pateikimo momentą, blokiruočių atleidimo eiliškumą, reakciją praradus ryšį arba programos elgseną po maitinimo dingimo. Būtent čia refaktorizavimo tema pereina į praktinį pakeitimų rizikos vertinimą: svarbu ne tai, ar kodas tapo „geresnis“, o ar po pakeitimo mašina, linija ar darbo vieta ir toliau elgiasi nuspėjamai normaliomis sąlygomis, sutrikimų metu ir po pakartotinio paleidimo.
Geras sprendimo brandos patikrinimas – įvertinti, ar komanda geba nustatyti ribą tarp programos vidinės struktūros pakeitimo ir proceso ar saugos požiūriu reikšmingos funkcijos pakeitimo. Jeigu šios ribos neįmanoma aprašyti signalų, būsenų ir perėjimo sąlygų lygmeniu, projektas yra rizikingas nepriklausomai nuo rangovo kokybės. Pramoninėje aplinkoje ypač jautrios yra situacijos, kai programa dalyvauja paleidimo, stabdymo, klaidų atstatymo, aliarmų patvirtinimo sekoje arba sąveikauja su energijos atjungimo grandinėmis ir blokiruotėmis. Tokiu momentu kyla jau ne vien programinės architektūros klausimas, bet ir apsauga nuo netikėto paleidimo, taip pat tai, ar analizė apima ir elektros instaliaciją, valdymo logiką bei priklausomybes tarp įrenginių. Būtent čia iš pažiūros lokalus refaktorizavimas nustoja būti IT užduotimi ir tampa techniniu pakeitimu, kuriam būtina taikyti visą sprendimų priėmimo tvarką.
Nuoroda į norminius reikalavimus čia tampa svarbi tik šiame etape, nes standartai nepakeičia projektinio sprendimo, tačiau padeda apibrėžti jo apimtį. Jeigu pakeitimas gali turėti įtakos paleidimo, stabdymo, darbo atkūrimo po sutrikimo sąlygoms arba apsaugos priemonėms, jį reikia vertinti kaip rizikos pakeitimą, o ne kaip įprastą kodo priežiūrą. Jeigu įsikišimas paliečia logiką, susijusią su energijos atjungimu, blokiruotėmis ar saugios prieigos seka, natūraliai atsiveria ir reikalavimų sritis, susijusi su apsauga nuo netikėto paleidimo. Atsakomybės požiūriu svarbiausia todėl yra ne pats klausimas „ar refaktorizuoti“, o tai, ar organizacija gali parodyti, kad žino pakeitimo ribas, turi proceso elgsena pagrįstus priėmimo kriterijus ir geba atskirti sistemos sutvarkymą nuo modifikacijos, kuriai būtinas rizikos vertinimas pagal ISO 12100 bei suderinimas su instaliacijos projektavimu ir bandymais objekte.
Kur dažniausiai didėja sąnaudos arba rizika
Didžiausias sąnaudų augimas pertvarkant seną pramoninę taikomąją programą retai kyla vien iš paties kodo. Problemos šaltinis paprastai yra neteisingas pakeitimo kvalifikavimas: komanda jį vertina kaip programos struktūros sutvarkymą, nors iš tikrųjų keičiasi sistemos elgsena laike, veiksmų seka arba perėjimo tarp būsenų sąlygos. Gamybinėje aplinkoje tokia klaida turi tiesioginių pasekmių projektui. Grafikas nebeatitinka realios darbų apimties, bandymai planuojami pagal IT funkcionalumą, o ne pagal proceso eigą, o atsakomybė už rezultatą išsiskaido tarp techninės priežiūros, automatikos specialistų ir programinės įrangos tiekėjo. Praktinis kriterijus čia paprastas: jeigu po pakeitimo reikia iš naujo patvirtinti paleidimo, sustabdymo, darbo atnaujinimo po sutrikimo seką arba reakciją į signalus iš apsauginių grandinių, tai jau nėra „saugi refaktorizacija“ organizacine prasme, o pakeitimas, galintis kelti riziką gamybai ir reikalaujantis kitokios tvirtinimo tvarkos.
Antra tipiška sąnaudų augimo sritis – projektinis sprendimas, priimtas neturint viso priklausomybių vaizdo. Senos pramoninės taikomosios programos dažnai yra glaudžiai susietos su valdiklio konfigūracija, vykdymo įrenginiais, vizualizacija, duomenų archyvavimu ir operatoriaus procedūromis. Dokumentacijoje tai atrodo kaip viena sistema, tačiau praktikoje tai yra sluoksniai, daugelį metų vystyti skirtingų komandų. Refaktorizacija, kuri turi pagerinti kodo skaitomumą arba palengvinti tolesnę priežiūrą, gali nepastebimai pakeisti delsų reikšmę, blokavimo sąlygas, numatytąsias reikšmes po perkrovimo arba ryšio klaidos apdorojimo būdą. Pasekmė – ne tik techninis taisymas, bet ir prastovų, papildomų bandymų objekte bei ginčų dėl to, ar trūkumas egzistavo anksčiau, ar buvo įvestas pakeitimu, sąnaudos. Todėl prieš priimant sprendimą verta vertinti ne vien modifikacijos dydį, bet ir sąsajų taškų skaičių bei kritiškumą: kiek signalų, receptūrų, darbo režimų ir eksploatacinių apeigų priklauso nuo kodo fragmento, kurį numatyta pertvarkyti. Kuo daugiau tokių taškų, tuo mažiau prasmės turi refaktorizacija, atliekama „ta pačia proga“ vykdant kitą užduotį.
Praktikoje ypač brangūs būna projektai, kuriuose komanda tikruosius reikalavimus atranda tik paleidimo metu. Tipinis pavyzdys – sekos modulio pertvarkymas, kuris pagal aprašą „daro tą patį, tik švariau“. Tačiau po įdiegimo paaiškėja, kad ankstesnėje versijoje buvo nedokumentuota elgsena, kompensuojanti objekto netobulumus: trumpas signalo palaikymas, tolerancija vėluojančiam jutikliui, specifinė aliarmo panaikinimo seka arba sąlyga, nuo kurios priklauso serviso prieigos galimybė. Kode tai atrodė kaip klaida arba techninė skola, tačiau procesui tai buvo stabilizavimo elementas. Jeigu refaktorizacija tokius mechanizmus pašalina, neišsiaiškinus jų funkcijos, sąnaudos atsiranda iš karto: daugėja intervencijų po paleidimo, ilgėja priėmimo laikas ir tenka atkurti logiką veikiant gamyklos darbo spaudimui. Todėl refaktorizacijos pagrįstumą reikia vertinti ir pagal galimybę atkurti dabartinės sistemos elgseną. Jeigu organizacija neturi įvykių registro, patikimų darbo režimų aprašų ir bandymų scenarijų, paremtų realiu procesu, pirmiausia reikia sukurti vertinimo pagrindą, o tik po to priimti sprendimą dėl pertvarkymo.
Ši tema tiesiogiai pereina į praktinį pakeitimų rizikos vertinimą tada, kai modifikacija daro įtaką apsauginėms funkcijoms, saugios prieigos sekoms, vykdymo elementų judėjimo valdymui arba įrenginio elgsenai dingus ir vėl atsiradus maitinimui. Tokiu atveju klaidos kaina neapsiriboja programavimo pataisymais, nes atsiranda ir atsakomybės už pakeitimo leidimą eksploatuoti klausimas. Jeigu taikomoji programa sąveikauja su hidraulinėmis, pneumatinėmis sistemomis arba sprendimais, tokiais kaip valdymas dviem rankomis, riba tarp refaktorizacijos ir techninio pakeitimo tampa dar siauresnė ir reikia patikrinti, ar nebuvo pažeistos apsaugos priemonių projektinės prielaidos. Būtent čia pagrįsta remtis struktūruotais pakeitimo rizikos vertinimo pagal ISO 12100 metodais, įskaitant praktikoje pagal ISO/TR 14121-2 taikomą požiūrį, o hidraulinių sistemų atveju – ir projektavimo reikalavimais, susistemintais pagal LST EN ISO 4413. Čia kalbama ne apie formalizmą dėl paties formalizmo, o apie paprastą sprendimų priėmimo principą: jeigu pakeitimas gali paveikti proceso ar eksploatavimo saugą, jo sąnaudas reikia skaičiuoti kartu su validavimu, bandymais objekte ir atsakomybės režimu, o ne vien pagal programuotojo darbo laiką.
Kaip prie to prieiti praktiškai
Praktikoje senos pramoninės programos refaktorizavimo pagrįstumas vertinamas ne pagal technologinį pakeitimo patrauklumą, o pagal tai, ar kartu galima sumažinti eksploatacinę riziką ir išlaikyti diegimo kontrolę. Vadovui ir produkto savininkui tai reiškia paprastą požiūrio pasikeitimą: klausimas yra ne tai, ar kodą „verta sutvarkyti“, bet ar dabartinė programos būklė realiai apsunkina priežiūrą, testavimą, gedimų šalinimą arba tolesnių pakeitimų diegimą laikantis reikalavimų. Jei atsakymas teigiamas, refaktorizavimas yra prasmingas, tačiau tik tokia apimtimi, kurią galima atskirti nuo gamybos darbo ir įvertinti pagal išmatuojamus padarinius. Geras sprendimo kriterijus čia yra dviejų sąnaudų palyginimas: programos palikimo dabartinės būklės kaina, apimanti prastovas, diagnostikos laiką, priklausomybę nuo pavienių asmenų ir klaidingo pakeitimo riziką, bei kontroliuojamo pertvarkymo kaina kartu su bandymais, validavimu ir paleidimu. Be tokio palyginimo projektas paprastai tampa sunkiai valdomas, nes komanda kodo tvarkymą finansuoja iš funkcionalumui skirto biudžeto, o atsakomybė už padarinius objekte lieka neapibrėžta.
Todėl pirmasis sprendimas turėtų būti ne „perrašome“ ar „paliekame“, o pakeitimo ribos nustatymas. Brandžiame požiūryje atskiriama dalis, susijusi tik su programinės įrangos struktūra, nuo dalies, darančios įtaką proceso logikai, paleidimo sekoms, stabdymui, darbo režimams, ryšiui su pavaromis ir sistemos elgsenai po maitinimo sutrikimo. Šis skirtumas turi tiesioginį poveikį sąnaudoms ir organizavimui. Pakeitimas, apribotas tik kodo sutvarkymo sluoksniu, gali būti vykdomas trumpesniu ciklu ir mažiau įtraukiant techninės priežiūros tarnybas. Pakeitimas, paliečiantis mašinos ar linijos elgseną, jau reikalauja bandymų objekte plano, techninės priežiūros lango, grąžinimo procedūros ir aiškiai nurodyto atsakingo asmens, kuris patvirtina leidimą eksploatuoti. Kartu verta matuoti ne tik programavimo darbų trukmę, bet ir sistemos atkūrimo laiką po nesėkmingo bandymo, regresiniais bandymais apimamų sričių skaičių bei laiką, reikalingą nuokrypiui po paleidimo diagnozuoti. Tai rodikliai, kurie parodo, ar refaktorizavimas iš tikrųjų mažina projekto riziką, o ne tik pagerina kūrimo komandos darbo komfortą.
Praktinis pavyzdys būdingas senesnėms valdymo programoms: kode yra daug kartų dubliuojami fragmentai, atsakingi už judėjimo blokavimus, aliarmų valdymą ir perėjimus tarp rankinio bei automatinio režimo. Komanda nori juos suvienodinti, nes dabartinė struktūra apsunkina plėtrą ir sukelia neatitikimų tarp darbo vietų. Toks sprendimas prasmingas tik patikrinus, ar suvienodinimas nepakeis sąlygų, kuriomis vykdomasis elementas gauna leidimą judėti, ir ar po valdiklio perkrovimo neatsiras kitokia būsenos atkūrimo seka. Jei programa taip pat valdo vožtuvus, pavaras ar sistemas su sukaupta energija, net iš pažiūros „vidinis“ refaktorizavimas gali pereiti į pakeitimo rizikos vertinimo pagal ISO 12100 sritį ir pareikalauti apsaugos nuo netikėto paleidimo pagal ISO 14118 analizės. Tokiu atveju pagrįsta praktika yra refaktorizavimą vykdyti etapais: pirmiausia atkurti elgseną bandymų aplinkoje, tada išskirti modulius nekeičiant logikos, o po to atlikti patikrą objekte pagal iš anksto parengtą grąžinimo scenarijų. Tai riboja eksploatacinę atsakomybę ir leidžia sustabdyti diegimą, kol problema dar nepaveikė gamybos.
Tik šiame etape prireikia norminio atskaitos taško, nes standartai nepakeičia techninio sprendimo, tačiau padeda aiškiai nustatyti momentą, kai pakeitimas nustoja būti vien programavimo darbu. Jei refaktorizavimas daro įtaką apsaugos priemonėms, saugios prieigos sąlygoms, energijos atjungimui arba sistemų elgsenai po sustabdymo ir pakartotinio paleidimo, jis natūraliai patenka į praktiškai atliekamo pakeitimų rizikos vertinimo sritį, vykdomą sistemiškai, taip pat taikant požiūrį, žinomą iš ISO/TR 14121-2. Kai atsiranda netikėto paleidimo rizika, reikia tikrinti jau ne vien patį kodą, bet ir energijos atjungimo bei atkūrimo logiką, o tai tiesiogiai veda prie klausimų, siejamų su ISO 14118. Jei programa susieta su hidraulika arba pneumatika, vertinant negalima nepaisyti šių sistemų projektinių prielaidų, nes klaidinga valdymo seka gali pažeisti jų saugų veikimą nepriklausomai nuo paties kodo teisingumo; tuomet pagrįsta remtis ir reikalavimais, kurie sistemina hidraulinių sistemų projektavimą. Praktikoje tai reiškia viena: refaktorizavimo apimtį lemia ne sprendimo elegancija, o atsakomybės už saugią įrenginio elgseną po pakeitimo riba.
Į ką atkreipti dėmesį diegiant
Senos pramoninės programos refaktorizavimo diegimas yra tas momentas, kai net teisingas architektūrinis sprendimas gali virsti eksploatacine problema. Visa šio darbo prasmė baigiasi ten, kur pakeitimas pagerina kodą, bet pablogina įrenginio darbo nuspėjamumą arba išplečia komandos atsakomybę už ribų to, kas buvo nustatyta ir patvirtinta. Dažniausia klaida – diegimą laikyti paprastu naujos versijos paskelbimu. Gamybinėje aplinkoje svarbu ne tik tai, ar programa veikia, bet ir ar po pakeitimo vienodai elgiasi visos pereinamosios būsenos: paleidimas po maitinimo dingimo, ryšio atkūrimas, receptūrų atkūrimas, aliarmų, blokavimų ir rankinių režimų valdymas. Praktinis kriterijus paprastas: jei komanda negali vienareikšmiškai aprašyti, kokia elgsena po diegimo turi likti nepakitusi, vadinasi, dar nėra sąlygų saugiam paleidimui.
Priimant sprendimą dėl diegimo, būtina atskirti techniškai grįžtamą pakeitimą nuo tokio, kuris po paleidimo sukuria naują pradinę būseną ir apsunkina grįžimą atgal. Tai tiesiogiai veikia sąnaudas ir grafiką. Refaktorizavimas, kuriam reikia vienu metu atnaujinti valdiklius, vizualizaciją, duomenų serverį ir sąsajas su aukštesnio lygmens sistemomis, nebėra pavienė programavimo užduotis; jis tampa koordinuotu gamybiniu pakeitimu su daugeliu galimų gedimo taškų. Todėl prieš diegimą verta taikyti priėmimo kriterijų, pagrįstą ne deklaracija „testai praėjo“, o galimybe kontroliuojamai atšaukti pakeitimą per procesui priimtiną laiką. Jeigu nėra patikimos grįžimo procedūros, nėra ir pagrindo teigti, kad rizika suvaldyta. Praktikoje verta matuoti ne abstrakčią „diegimo kokybę“, o tokius rodiklius kaip ankstesnės versijos atkūrimo laikas, nuo pakeitimo priklausančių sąsajų skaičius ir funkcijų, kurių teisingumą galima patvirtinti įrenginyje nesikišant į gamybą, skaičius.
Geras pavyzdys – situacija, kai refaktorizavimas sutvarko išimčių ir klaidų pranešimų apdorojimą, bet kartu pakeičia inicializavimo seką po sistemos paleidimo iš naujo. Bandymų stende viskas atrodo teisingai, nes įrenginiai pasiekiami iš karto, o procesas neveikia esant apkrovai. Tačiau gamykloje tas pats kodas gali paleisti seką kitu momentu nei anksčiau, o tai lemia sinchronizacijos su pavaromis praradimą, neteisingą parengties signalų interpretavimą arba medžiagos partijos sustabdymą tarpinėje būsenoje. Toks incidentas nebūtinai reiškia techninį gedimą, tačiau sukelia prastovos, broko, pakartotinio paleidimo sąnaudas ir papildomą atsakomybę priimant sprendimą atnaujinti darbą. Būtent čia refaktorizavimo tema pereina į praktinį pakeitimų rizikos vertinimą: ne tada, kai pakeitimas yra didelis, o tada, kai jo padarinių nebeįmanoma apriboti vien programine dalimi.
Atsakomybės riba tampa dar aiškesnė ten, kur taikomoji programa daro įtaką apsauginėms funkcijoms, leidimo judėti logikai, apkrovos nuėmimo sekoms, sustabdymui ir pakartotiniam paleidimui po sutrikimo. Tokiu atveju vien kodo versijų palyginimo ar integratoriaus atlikto funkcinio bandymo jau nepakanka. Reikalingas nuoseklus įvertinimas, ar pakeitimas keičia rizikos lygį ir ar nepažeidžia saugaus mašinos ar įrenginio veikimo prielaidų. Tai natūralus momentas pereiti į rizikos vertinimo pagal ISO 12100 sritį pagal ISO 12100 ir praktiką, taikomą vertinant pakeitimų riziką, o sudėtingesniais atvejais naudingas būna metodinis požiūris, žinomas iš ISO/TR 14121-2. Jeigu taikomoji programa valdo hidraulines arba pneumatines sistemas, papildomai reikia patikrinti, ar naujoji logika nekeičia saugaus energijos valdymo sąlygų ir judesių sekos; tuomet svarbūs tampa ir šioms sistemoms taikomi projektavimo reikalavimai, o ne vien pačios programos teisingumas. Projektavimo komandai tai reiškia viena: diegimą galima laikyti parengtu tik tada, kai techninės, eksploatacinės ir atitikties atsakomybės apimtis yra įvardyta prieš paleidimą, o ne tik po pirmojo incidento.
Senos pramoninės programos refaktorizavimas – kada tai prasminga ir kaip tai atlikti nekeliant rizikos gamybai?
Tai prasminga tada, kai nedidelių pakeitimų diegimo sąnaudos ir neapibrėžtumas auga greičiau nei jų verslo vertė. Tai signalas, kad technologinė skola pradeda daryti poveikį gamybos tęstinumui ir veiklos sąnaudoms.
Kai pakeitimas turi įtakos signalams, būsenoms, perėjimo sąlygoms arba paleidimo, sustabdymo ir darbo atnaujinimo sekoms. Tuomet tai jau nėra vien architektūros klausimas, o techninis pakeitimas, kuriam būtinas rizikos vertinimas.
Dažniausiai ten, kur laikui bėgant keičiasi sistemos veikimas: užduočių grafikas, veiksmų seka, buferiavimo logika, reakcija praradus ryšį arba dingus maitinimui. Net ir nedidelis įsikišimas tokiu atveju gali pakeisti numatomą mašinos ar linijos veikimo nuspėjamumą.
Būtina aiškiai nustatyti ribą tarp taikomosios programos struktūros pakeitimo ir procesui ar saugai svarbios funkcijos pakeitimo. Priėmimo kriterijai turėtų būti grindžiami proceso veikimu, o bandymai turėtų apimti ir įprastines, trikdžių bei pakartotinio paleidimo būsenas.
Kai pakeitimas susijęs su logika, valdančia paleidimą, sustabdymą, klaidų atstatymą, blokuotes, energijos atjungimą arba saugią prieigą. Tokiais atvejais pakeitimas turi būti laikomas rizikos pakeitimu, o ne įprasta kodo priežiūra.