Toate articolele
Software reglementat · 4 min citire ·

Cum modernizezi C++ legacy fără să pierzi conformitatea

Refactorizarea codului vechi într-un produs reglementat nu e blocată de standard, ci de trasabilitate. Strategia care funcționează: schimbări mici, izolate, cu o poveste clară a echivalenței.

C++legacyrefactoringsoftware medical

Acest articol e perspectiva unui inginer care a lucrat sub aceste cerințe, nu consultanță de reglementare. Pentru decizii de conformitate, consultă specialistul vostru de calitate/reglementare.

Mult din software-ul medical care rulează azi e C++ scris acum zece sau douăzeci de ani. Funcționează, e validat, și nimeni nu vrea să-l atingă. Până când trebuie: apare o cerință nouă, un compilator care nu mai e suportat, sau o bibliotecă cu o vulnerabilitate.

Am petrecut ani buni în zona asta — componente de imagistică în timp real la GE Healthcare și cod de sistem de date de laborator la Waters. Ce urmează e ce am învățat despre cum se face fără să dai totul peste cap.

De ce e diferită modernizarea sub reglementare?

În software obișnuit, un refactor bun e cel care nu schimbă comportamentul observabil. Sub reglementare, cerința e mai dură: trebuie să poți demonstra că nu l-a schimbat.

Diferența e enormă. „Sunt destul de sigur că merge la fel“ nu e un argument. Ai nevoie de dovezi — testele dinainte, testele de după, și o legătură clară între ce ai schimbat și ce ai verificat.

Asta face ca marile rescrieri să fie aproape imposibil de justificat. Nu pentru că sunt interzise, ci pentru că efortul de a demonstra echivalența pentru un sistem întreg e disproporționat.

Cum începi când nu ai teste?

Cazul obișnuit: cod fără teste, fără documentație de design, cu autori plecați de mult.

Ordinea care funcționează:

  1. Teste de caracterizare înainte de orice. Nu teste „corecte“ — teste care capturează comportamentul actual, inclusiv ciudățeniile. Baza de comparație e sistemul de azi, nu specificația ideală.
  2. Găsește cusăturile. Punctele unde poți introduce un test fără să rescrii jumătate din modul: o interfață, un punct de intrare, o funcție liberă.
  3. Îngheață comportamentul la graniță. Dacă poți testa intrările și ieșirile unui modul, ai libertate completă înăuntru.
  4. Abia apoi schimbă.

Punctul 1 e cel pe care echipele îl sar cel mai des, sub presiunea timpului. E și cel care costă cel mai mult când lipsește.

Ce înseamnă „echivalență“ și de ce contează?

Când modifici cod validat, întrebarea la care trebuie să răspunzi e: rezultatul rămâne același acolo unde contează?

Pentru cod numeric — procesare de semnal, calcule pe măsurători — asta e mai subtil decât pare. O reorganizare de operații în virgulă mobilă poate schimba ultimul bit al rezultatului. Uneori nu contează. Alteori, dacă rezultatul trece printr-un prag de decizie, contează foarte mult.

Ce ajută:

  • definește explicit toleranța acceptabilă, nu presupune „identic bit cu bit“;
  • rulează comparații pe seturi mari de date reale (sau reprezentative), nu pe trei cazuri;
  • documentează diferențele găsite și de ce sunt acceptabile.

Argumentul de echivalență e artefactul care convinge. Fără el, ai doar o promisiune.

Cum împarți munca ca să nu declanșezi re-validare masivă?

Principiul care m-a ajutat cel mai mult: nu amesteca niciodată refactorizarea cu schimbarea de comportament.

  • un commit care mută cod, redenumește, extrage funcții — fără nicio schimbare de comportament;
  • un commit separat, mic, care schimbă comportamentul intenționat.

Când cele două se amestecă, nimeni nu mai poate spune ce a cauzat o diferență, iar analiza de impact devine o presupunere.

În plus:

  • izolează zonele cu risc mai mare ca să nu contaminezi restul sistemului cu clasa lor de siguranță;
  • grupează schimbările pe module, ca re-testarea să fie delimitată;
  • tratează schimbarea de toolchain ca pe o schimbare reală — un compilator nou e o modificare care poate afecta comportamentul, nu un detaliu de infrastructură.

Ce tehnici C++ ajută cel mai mult?

Din experiență, în ordinea raportului beneficiu/risc:

  • RAII, introdus treptat. Înlocuirea gestionării manuale a resurselor elimină o clasă întreagă de defecte, iar schimbarea e local verificabilă.
  • const-corectitudine. Ieftină, prinde erori la compilare, nu schimbă comportamentul.
  • Eliminarea comportamentului nedefinit. UB-ul e cel mai periculos în cod vechi: funcționează până schimbi compilatorul. Sanitizer-ele găsesc mult, rapid.
  • Restrângerea vizibilității. Mutarea a ce se poate în unități de traducere private reduce suprafața de impact a schimbărilor viitoare.
  • Tipuri explicite în locul conversiilor implicite, mai ales la granițele numerice.

Ce am învățat să evit: adoptarea entuziastă a fiecărei facilități noi de limbaj. Fiecare schimbare trebuie justificată prin beneficiu, nu prin modernitate.

Ce să nu faci

  1. Rescrierea de la zero. Aproape niciodată justificabilă: pierzi ani de corecții subtile care nu sunt documentate nicăieri.
  2. Refactor „de curățenie“ pe zone pe care nu le atingi funcțional. Fiecare atingere are cost de verificare. Curățenia gratuită nu există aici.
  3. Actualizarea simultană a compilatorului și a codului. Când apare o diferență, nu vei ști de la care.
  4. Ignorarea dependențelor terțe. Fiecare bibliotecă e o componentă cu evidența ei; actualizarea nu e „doar un bump de versiune“.

Modernizarea sub reglementare e mai lentă, dar nu e imposibilă. E, în esență, aceeași disciplină pe care ar trebui s-o aplicăm oriunde — doar că aici nu e opțională.

Dacă ai un sistem vechi pe care trebuie să-l duci mai departe fără să-l destabilizezi, e exact genul de problemă pe care am lucrat.

Unde am lucrat sub aceste cerințe

  • GE Healthcare — Voluson Ultrasound

    Software Engineer (contract, remote)

    dec. 2022 – ian. 2025

  • Capgemini — client Waters Corporation

    Software Engineer (contract)

    iun. 2022 – mai 2023

Proiectul din spatele articolului MedVital — Monitorizare Semne Vitale în Timp Real Motor C++20 de monitorizare a semnelor vitale, cu pipeline de procesare și streaming live — proiect personal de inginerie.

Ai un proiect similar?

Dacă lucrezi la ceva din zona asta, hai să vorbim 30 de minute.

Programează o discuție
Toate articolele