Frankenstein în programare — ce este, cauze și prevenire

Autor: IT Sectr Publicat: 2026-07-26 Timp de citire: 10 min

Frankenstein în programare este codul format din părți incompatibile ale diferitelor tehnologii, stiluri și arhitecturi. Conform cercetării ThoughtWorks Technology Radar (2024), 28% dintre proiectele mari conțin semne ale sindromului Frankenstein — un eclectism arhitectural care apare în absența unei viziuni tehnice unitare. Prin analogie cu romanul lui Mary Shelley, un astfel de cod funcționează, dar întreținerea sa devine un coșmar.

Principalele

  • Frankenstein — un antipattern în care sistemul este asamblat din componente eterogene, slab compatibile
  • Cauzele principale: lipsa arhitectului, fuziunea proiectelor, „creativitate fără limite”
  • Problema — fiecare componentă necesită cunoașterea tehnologiei sale, iar interacțiunile sunt imprevizibile
  • Refactorizarea Frankenstein necesită unificarea stivei tehnologice și stabilirea unor limite clare
  • Architecture Decision Records și RFC — cele mai bune instrumente de prevenire

Ce este Frankenstein în programare

Frankenstein (Frankenstein code, Frankenstein pattern) — este un antipattern în care un sistem software este asamblat din părți care nu sunt destinate să lucreze împreună. Ca monstrul lui Frankenstein, un astfel de cod poate funcționa, dar este urât, imprevizibil și periculos la cele mai mici modificări.

Termenul provine din literatură: în romanul Mary Shelley „Frankenstein sau Prometeu modern” (1818), un savant a creat o ființă vie din fragmente ale trupurilor diferiților morți. În programare, analogia este exactă — dezvoltatorii iau fragmente din diferite framework-uri, biblioteci, limbaje și le „lipesc pe viu”, obținând un rezultat funcțional, dar monstruos.

Diferența dintre Frankenstein și codul spaghete constă în amploarea și natura problemei. Codul spaghete — este o structură încurcată în cadrul unei singure stive tehnologice. Frankenstein — este un eclectism la nivel de arhitectură: tehnologii diferite, paradigme incompatibile, abordări conflictuale în cadrul unui singur sistem.

Frankenstein vs microservicii

Arhitectura microserviciilor permite utilizarea unor tehnologii diferite pentru servicii diferite, dar cu condiția unor limite clare și a unor protocoale de comunicare standardizate. Frankenstein — este o amestecătură haotică fără limite: REST și GraphQL în același controler, două ORM-uri în același modul, SQL și NoSQL pentru aceeași entitate.

De ce apare sindromul Frankenstein

Lipsa unui lider tehnic sau arhitect — cauza principală. Când în proiect nu există o persoană responsabilă pentru integritatea arhitecturii, fiecare dezvoltator alege instrumentele „după sine”. Unul preferă Spring, altul — Guice, al treilea — propriul DI scris de mână. Rezultatul — un vinegret arhitectural.

Fuziunea proiectelor — a doua cauză frecventă. Două echipe și-au dezvoltat modulele independent, folosind stive tehnologice diferite. Când modulele trebuie să fie unite într-o singură aplicație, ele sunt pur și simplu „lipite” cu adaptoare și straturi intermediare. Rezultă Frankenstein.

Achizițiile corporative — al treilea scenariu. Compania A a cumpărat compania B și dorește să integreze produsul său în propriul său produs. În loc de rescriere — lipire prin API, baze de date comune și proteze. După un an, sistemul se transformă într-un monstru pe care nimeni nu îl înțelege.

CauzăDescriereRezultat tipic
Fără arhitectFiecare dezvoltator alege propria stivă3 clienți HTTP diferiți în același modul
Fuziunea proiectelorDouă produse sunt lipite într-unulDouă ORM-uri, două metode de logare
M&AAchiziția companiei cu produsul săuHibrid de arhitecturi și stiluri diferite
ExperimenteImplementarea de noi tehnologii fără strategieJava 8 + Java 21 în același fișier
Decizii politiceImpunerea tehnologiei de sus fără a ține cont de contextFramework enterprise pentru un script simplu

Factorul „creativitate”

Dezvoltatorii experimentați care doresc să încearnce tehnologii noi în producție devin adesea sursa lui Frankenstein. În loc să limiteze experimentele la un modul izolat, ei introduc cod experimental în partea critică a sistemului.

Exemple de Frankenstein în proiecte reale

Exemplul clasic — utilizarea mai multor ORM-uri într-o singură aplicație. O parte din module folosesc Hibernate, o parte — MyBatis, iar o parte — interogări directe JDBC. Tranzacțiile devin imposibil de gestionat, memoria cache — inconsistentă, iar un nou dezvoltator nu știe ce abordare să aleagă pentru o funcție nouă.

Al doilea exemplu — amestecarea stilurilor arhitecturale. Într-un controler REST API apar apeluri către servicii SOAP, interogări SQL directe, acces la sistemul de fișiere și generare HTML. O astfel de aplicație nu poate fi testată, extinsă sau documentată.

Al treilea exemplu — o stivă tehnologică în care Python este folosit pentru backend, Node.js pentru microserviciu, C# pentru clientul desktop, iar Java pentru aplicația Android, în timp ce toată logica de afaceri este dispersată între ele fără o separare clară a responsabilităților.

javascript
// frankenstein — stiluri și tehnologii mixte
// callbacks, Promises și async/await combinate

// callbacks
db.query("SELECT * FROM users", function(err, rows) {
  if (err) handleError(err);
  // Promise în interiorul callback
  fetch("/api/data").then(function(data) {
    // async/await în interiorul then
    (async () => {
      const result = await processData(data);
      sendResponse(result);
    })();
  });
});

// cod curat — stil unificat async/await
async function getUserData(userId) {
  const user = await db.query("SELECT * FROM users WHERE id = ?", [userId]);
  const data = await fetch("/api/data/" + userId);
  return await processData(user, data);
}

Frankenstein la nivel de date

O singură bază de date este utilizată simultan atât ca SQL relațional (cu normalizare), cât și ca NoSQL orientat pe documente (cu coloane JSON). O parte din interogări trec prin ORM, o parte — prin proceduri stocate, o parte — prin SQL direct din cod. Schema bazei de date nu este documentată, migrațiile sunt conflictuale.

Consecințele codului Frankenstein

Dificultatea onboardingu — prima consecință. Un nou dezvoltator trebuie să cunoască 5 limbi, 3 framework-uri, 2 stiluri arhitecturale pentru a înțelege cum funcționează sistemul. Onboardingul se prelungește de la săptămâni la luni. Conform LinkedIn (2023), proiectele cu eclectism tehnologic pierd noii angajați de 2 ori mai des.

Imprevizibilitatea comportamentului — a doua consecință. O modificare într-un microserviciu Python poate strica neașteptat un modul Java, deoarece acestea folosesc o bază de date comună fără contracte clare. Depanarea unor astfel de probleme necesită cunoașterea simultană a tuturor tehnologiilor din stivă.

Securitatea — a treia consecință. Fiecare tehnologie din stivă necesită propria configurație de securitate, propriile patch-uri, propriul monitorizare. Menținerea securității la un nivel acceptabil pentru 5–6 tehnologii eterogene este practic imposibilă. Una dintre ele va fi inevitabil vulnerabilă.

Datoria tehnică a lui Frankenstein

SonarQube poate măsura datoria tehnică, dar nu poate măsura „datoria arhitecturală” — incompatibilitatea componentelor. Această datorie nu se manifestă în avertismentele linter-ului, ci în imposibilitatea de a adăuga o nouă funcție fără a modifica trei module diferite scrise în tehnologii diferite.

Cum să evitați crearea unui monstru

Primul și cel mai important pas — numirea unui arhitect sau tech lead responsabil pentru integritatea stivei tehnologice. Această persoană are drept de veto asupra implementării noilor tehnologii fără o revizuire arhitecturală. Nu democrație, ci o decizie responsabilă individuală în privința tehnologiilor cheie.

Al doilea — implementarea procesului Architecture Decision Record (ADR). Orice decizie arhitecturală semnificativă (alegerea bazei de date, framework-ului, protocolului) este documentată sub forma unui text scurt: context, alternativele luate în considerare, decizia luată, consecințele. ADR-urile sunt stocate în repository și accesibile întregii echipe.

Al treilea — stabilirea principiului „o sarcină — un instrument”. Pentru cereri HTTP — un client. Pentru ORM — o bibliotecă. Pentru logare — un framework. Excepțiile sunt permise doar prin ADR cu justificare. Dacă în proiect există deja Axios — nu adăugați fetch, dacă există SLF4J — nu scrieți prin System.out.

  • Arhitect cu drept de veto asupra noilor tehnologii
  • Architecture Decision Records pentru fiecare alegere semnificativă
  • Stivă unică pentru fiecare sarcină — un client HTTP, un ORM
  • RFC pentru modificări majore cu discuția întregii echipe
  • Radar tehnologic pentru urmărirea a ceea ce poate fi implementat

Politica tehnologiilor experimentale

Experimentele sunt permise, dar într-un mediu izolat. Alocați un modul sau un serviciu care poate fi rescris într-o tehnologie nouă fără a afecta restul sistemului. Dacă experimentul reușește — standardizați-l prin ADR. Dacă nu — ștergeți-l fără consecințe.

Cum să refactorizați un Frankenstein existent

Inventarierea — primul pas. Întocmiți o hartă completă a stivei tehnologice: ce framework-uri, biblioteci, limbaje, protocoale sunt utilizate, în ce module și pentru ce sarcini. Veți vedea amploarea problemei: duplicarea instrumentelor, tehnologii conflictuale, dependențe neutilizate.

Standardizarea — al doilea pas. Alegeți un instrument pentru fiecare sarcină. De exemplu: doar Hibernate pentru ORM, doar SLF4J + Logback pentru logare, doar REST pentru API. Documentați standardul în ADR. Începeți înlocuirea de la modulele unde eclectismul cauzează cele mai multe probleme.

Strategia Parallel Run — al treilea pas. Instrumentele vechi și noi funcționează în paralel până când cel nou își dovedește fiabilitatea. De exemplu, clientul HTTP vechi și cel nou funcționează simultan, dar cel nou — doar pentru o parte din cereri. După o perioadă de stabilizare, cel vechi este eliminat.

java
// frankenstein — trei abordări HTTP într-un singur proiect
// Modulul A: OkHttp
OkHttpClient client = new OkHttpClient().newCall(request);

// Modulul B: RestTemplate (Spring)
restTemplate.getForObject(url, String.class);

// Modulul C: java.net.HttpURLConnection
HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();

// abordare unificată: RestTemplate pentru sincron, WebClient pentru reactiv
@Autowired
private RestTemplate restTemplate;

public String callApi(String url) {
    return restTemplate.getForObject(url, String.class);
}

Rolul liderului tehnic în prevenire

Liderul tehnic — principalul instrument de luptă împotriva lui Frankenstein. Nu un manager, nu un arhitect în turnul de fildeș, ci un dezvoltator practicant care scrie cod, revizuiește PR-uri și ia decizii arhitecturale. Fără o astfel de persoană, proiectul alunecă inevitabil spre eclectism tehnologic.

RFC (Request for Comments) — un proces preluat din comunitățile Open Source. Înainte de implementarea oricărei tehnologii semnificative, autorul scrie un RFC: problema, soluția propusă, alternativele, planul de implementare. Echipa discută, votează, acceptă sau respinge. RFC creează transparență și previne deciziile arhitecturale „tăcute”.

Radarul tehnologic (Technology Radar de la ThoughtWorks) — un instrument de categorizare a tehnologiilor: Adopt, Trial, Assess, Hold. Echipa revizuiește periodic radarul și actualizează statusurile. Acest lucru ajută la deosebirea „modului” de „util” și la evitarea implementării tehnologiilor netestate în codul critic.

Principiul coerenței

Cea mai importantă calitate a arhitecturii este coerența (consistency). Chiar și un instrument nu cel mai bun, utilizat în întregul proiect, este mai bun decât cel mai bun instrument utilizat doar într-un singur modul. Coerența reduce sarcina cognitivă, simplifică onboardingul și face codul previzibil.

Întrebări frecvente

Cu ce diferă Frankenstein de utilizarea polyglot persistence?

Polyglot persistence — utilizarea conștientă a diferitelor baze de date pentru diferite sarcini (PostgreSQL pentru tranzacții, Redis pentru cache, Elasticsearch pentru căutare). Frankenstein — o amestecătură haotică fără strategie. Diferența constă în existența unei decizii arhitecturale: polyglot — este un plan, Frankenstein — absența acestuia.

Poate arhitectura microserviciilor să se transforme în Frankenstein?

Da, și aceasta este o problemă frecventă. Când fiecare microserviciu folosește propriul limbaj, propria bază de date, propriul protocol și propria abordare de implementare fără standarde centralizate, se obține un Frankenstein distribuit. Pentru microservicii sunt importante standardele comune: un protocol unic (REST/gRPC), un format comun de loguri, un observability centralizat.

Cum să convingeți echipa să nu folosească o tehnologie nouă?

Nu interziceți — ghidați. Propuneți autorului să scrie un RFC: să descrie de ce soluția existentă nu este potrivită, ce alternative a luat în considerare, cum va migra. Adesea în procesul de scriere a RFC-ului, dezvoltatorul înțelege singur că noua tehnologie nu este necesară. Dacă RFC este convingător — implementați, dar cu un plan și limitări.

Cum să luptați cu Frankenstein într-un proiect moștenit?

Mai întâi inventarierea, apoi standardizarea. Nu încem să rescrieți totul deodată. Separați un strat (de exemplu, clienții HTTP sau logarea), alegeți un instrument unic, scrieți un ADR și migrați treptat. Metoda Strangler Fig — înlocuiți componentele vechi cu cele noi una câte una, fără a opri funcționarea aplicației.

Câte tehnologii sunt optime pentru un proiect?

Cu cât mai puține, cu atât mai bine. Ideal — un limbaj, un framework, o bază de date, o metodă de logare. Realist — 2–3 limbaje (cu separare clară), 1–2 baze de date, 1–2 framework-uri. Fiecare tehnologie suplimentară crește sarcina cognitivă a echipei și costul de întreținere.

Rezumat

  • Frankenstein — antipattern în care sistemul este format din componente eterogene incompatibile
  • Cauzele principale: lipsa arhitectului, fuziunea proiectelor, experimente necontrolate
  • Consecințele — onboarding dificil, comportament imprevizibil, probleme de securitate
  • ADR și RFC — procese cheie pentru prevenirea eclectismului arhitectural
  • Principiul „un instrument pe sarcină” — baza prevenirii
  • Refactorizarea începe cu inventarierea și standardizarea stivei tehnologice
  • Coerența arhitecturii este mai importantă decât „cea mai bună unealtă” pentru o subsarcină

Vom dezvolta o aplicație mobilă la cheie

IT Sectr creează aplicații iOS și Android pentru startup-uri și afaceri din 2017. Vă vom consilia și vă vom propune cea mai bună soluție.

Discutați proiectul

Citiți și