Frankenstein nella programmazione — definizione, cause e prevenzione

Autore: IT Sectr Pubblicato: 2026-07-26 Tempo di lettura: 10 min

Frankenstein nella programmazione è codice assemblato da parti incompatibili di diverse tecnologie, stili e architetture. Secondo la ricerca ThoughtWorks Technology Radar (2024), il 28% dei grandi progetti mostra segni della sindrome di Frankenstein — eclettismo architettonico che nasce dall'assenza di una visione tecnica unificata. Per analogia con il romanzo di Mary Shelley, tale codice funziona, ma la sua manutenzione diventa un incubo.

Punti chiave

  • Frankenstein è un anti-pattern in cui il sistema è assemblato da componenti eterogenei e poco compatibili
  • Cause principali: mancanza di un architetto, fusione di progetti, “creatività senza limiti”
  • Il problema — ogni componente richiede conoscenza della propria tecnologia e l'interazione è imprevedibile
  • Rifattorizzare Frankenstein richiede l'unificazione dello stack tecnologico e la definizione di confini chiari
  • Architecture Decision Records e RFC sono i migliori strumenti di prevenzione

Cos'è Frankenstein nella programmazione

Frankenstein (codice Frankenstein, pattern Frankenstein) è un anti-pattern in cui un sistema software è assemblato da parti non progettate per lavorare insieme. Come il mostro di Frankenstein, tale codice può funzionare, ma è brutto, imprevedibile e pericoloso al minimo cambiamento.

Il termine viene dalla letteratura: nel romanzo di Mary Shelley “Frankenstein, o il Prometeo moderno” (1818), uno scienziato creò un essere vivente da frammenti di corpi di diversi morti. Nella programmazione, l'analogia è esatta — gli sviluppatori prendono pezzi di diversi framework, librerie, linguaggi e li incollano “vivi”, ottenendo un risultato funzionante ma mostruoso.

La differenza tra Frankenstein e il codice spaghetti sta nella scala e nella natura. Il codice spaghetti è una struttura aggrovigliata all'interno di un singolo stack tecnologico. Frankenstein è eclettismo a livello di architettura: diverse tecnologie, paradigmi incompatibili, approcci conflittuali all'interno dello stesso sistema.

Frankenstein vs Microservizi

L'architettura a microservizi permette di usare diverse tecnologie per diversi servizi, ma a condizione di confini chiari e protocolli di interazione standardizzati. Frankenstein è una miscela caotica senza confini: REST e GraphQL nello stesso controller, due ORM nello stesso modulo, SQL e NoSQL per la stessa entità.

Perché si manifesta la sindrome di Frankenstein

L'assenza di un leader tecnico o di un architetto è la causa principale. Quando non c'è una persona responsabile dell'integrità architettonica, ogni sviluppatore sceglie strumenti “per sé”. Uno ama Spring, un altro Guice, un terzo usa un DI personalizzato. Il risultato — un miscuglio architettonico.

La fusione di progetti è la seconda causa comune. Due team hanno sviluppato i loro moduli indipendentemente, usando stack diversi. Quando i moduli devono essere combinati in un'unica applicazione, vengono semplicemente “incollati” con adattatori e middleware. Il risultato è Frankenstein.

Le acquisizioni aziendali sono il terzo scenario. L'azienda A ha comprato l'azienda B e vuole integrare il suo prodotto nel proprio. Invece di riscrivere — incollaggio tramite API, database condivisi e cerotti. Dopo un anno, il sistema diventa un mostro che nessuno capisce.

CausaDescrizioneRisultato tipico
Nessun architettoOgni sviluppatore sceglie il proprio stack3 client HTTP diversi in un modulo
Fusione progettiDue prodotti incollati in unoDue ORM, due modi di logging
M&AAcquisizione azienda con suo prodottoIbrido di diverse architetture e stili
EsperimentiIntroduzione nuove tecnologie senza strategiaFeature Java 8 + Java 21 in un file
Decisioni politicheTecnologia imposta dall'alto senza contestoFramework enterprise per script semplice

Il fattore “creatività”

Gli sviluppatori esperti che vogliono provare nuove tecnologie in produzione diventano spesso la fonte di Frankenstein. Invece di limitare gli esperimenti a un modulo isolato, introducono codice sperimentale in parti critiche del sistema.

Esempi di Frankenstein in progetti reali

Un esempio classico è l'uso di più ORM in una singola applicazione. Alcuni moduli usano Hibernate, alcuni MyBatis, e alcuni query JDBC dirette. Le transazioni diventano ingestibili, la cache incoerente, e un nuovo sviluppatore non sa quale approccio usare per una nuova funzionalità.

Un secondo esempio è la mescolanza di stili architettonici. In un controller REST API, trovi chiamate a servizi SOAP, query SQL dirette, accesso al filesystem e generazione HTML. Un'applicazione del genere è impossibile da testare, estendere o documentare.

Un terzo esempio è uno stack tecnologico dove Python è usato per il backend, Node.js per un microservizio, C# per un client desktop e Java per un'app Android, mentre tutta la logica di business è sparsa tra loro senza una chiara separazione delle responsabilità.

javascript
// Frankenstein — stili e tecnologie misti
// callbacks, Promises e async/await combinati

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

// codice pulito — stile async/await unificato
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 a livello di dati

Un singolo database è usato simultaneamente come SQL relazionale (con normalizzazione) e come NoSQL orientato ai documenti (con colonne JSON). Alcune query passano tramite ORM, alcune tramite procedure memorizzate, alcune tramite SQL diretto dal codice. Lo schema del DB non è documentato, le migrazioni entrano in conflitto.

Conseguenze del codice Frankenstein

La complessità di onboarding è la prima conseguenza. Un nuovo sviluppatore deve conoscere 5 linguaggi, 3 framework, 2 stili architettonici per capire come funziona il sistema. L'onboarding si estende da settimane a mesi. Secondo LinkedIn (2023), i progetti con eclettismo tecnologico perdono i nuovi dipendenti 2 volte più spesso.

L'imprevedibilità del comportamento è la seconda conseguenza. Una modifica nel microservizio Python può rompere inaspettatamente il modulo Java perché condividono un database senza contratti chiari. Debuggare tali problemi richiede conoscenza simultanea di tutte le tecnologie nello stack.

La sicurezza è la terza conseguenza. Ogni tecnologia nello stack richiede la propria configurazione di sicurezza, le proprie patch, il proprio monitoraggio. Mantenere la sicurezza a un livello accettabile per 5-6 tecnologie eterogenee è praticamente impossibile. Una di esse sarà inevitabilmente vulnerabile.

Il debito tecnico di Frankenstein

SonarQube può misurare il debito tecnico, ma non può misurare il “debito architettonico” — l'incompatibilità dei componenti. Questo debito si manifesta non negli avvisi del linter, ma nell'impossibilità di aggiungere una nuova funzionalità senza modificare tre moduli diversi scritti in tecnologie diverse.

Come evitare di creare un mostro

Il primo e principale passo è nominare un architetto o tech lead responsabile dell'integrità dello stack tecnologico. Questa persona ha potere di veto sull'introduzione di nuove tecnologie senza revisione architettonica. Non democrazia, ma decisione individuale responsabile sulle tecnologie chiave.

Il secondo passo è implementare il processo Architecture Decision Record (ADR). Ogni decisione architettonica significativa (scelta di DB, framework, protocollo) è documentata come un testo breve: contesto, alternative considerate, decisione presa, conseguenze. Gli ADR sono memorizzati nel repository e disponibili a tutto il team.

Il terzo passo è stabilire il principio “un compito — uno strumento”. Per le richieste HTTP — un client. Per ORM — una libreria. Per il logging — un framework. Le eccezioni sono consentite solo tramite ADR con giustificazione. Se il progetto ha già Axios — non aggiungere fetch, se ha SLF4J — non scrivere tramite System.out.

  • Architetto con potere di veto sulle nuove tecnologie
  • Architecture Decision Records per ogni scelta significativa
  • Stack unificato per ogni compito — un client HTTP, un ORM
  • RFC per cambiamenti importanti con discussione di tutto il team
  • Radar tecnologico per tracciare cosa può essere adottato

Politica delle tecnologie sperimentali

Gli esperimenti sono consentiti, ma in un ambiente isolato. Alloca un modulo o servizio che può essere riscritto con una nuova tecnologia senza influenzare il resto del sistema. Se l'esperimento ha successo — standardizzalo tramite ADR. Se no — rimuovilo senza conseguenze.

Come rifattorizzare un Frankenstein esistente

Inventario — il primo passo. Crea una mappa completa dello stack tecnologico: quali framework, librerie, linguaggi, protocolli sono usati, in quali moduli e per quali compiti. Vedrai la portata del problema: duplicazione di strumenti, tecnologie in conflitto, dipendenze inutilizzate.

Standardizzazione — il secondo passo. Scegli uno strumento per ogni compito. Per esempio: solo Hibernate per ORM, solo SLF4J + Logback per logging, solo REST per API. Documenta lo standard in ADR. Inizia la sostituzione dai moduli dove l'eclettismo causa più problemi.

Strategia Parallel Run — il terzo passo. Lo strumento vecchio e quello nuovo funzionano in parallelo finché il nuovo non prova la sua affidabilità. Per esempio, il vecchio client HTTP e il nuovo funzionano simultaneamente, ma il nuovo gestisce solo una parte delle richieste. Dopo un periodo di stabilizzazione, il vecchio viene rimosso.

java
// Frankenstein — tre approcci HTTP in un progetto
// Modulo A: OkHttp
OkHttpClient client = new OkHttpClient().newCall(request);

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

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

// approccio unificato: RestTemplate per sincrono, WebClient per reattivo
@Autowired
private RestTemplate restTemplate;

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

Il ruolo del leader tecnico nella prevenzione

Un leader tecnico è lo strumento principale per combattere Frankenstein. Non un manager, non un architetto in una torre d'avorio, ma uno sviluppatore praticante che scrive codice, revisiona le PR e prende decisioni architettoniche. Senza una tale persona, il progetto scivola inevitabilmente nell'eclettismo tecnologico.

RFC (Request for Comments) è un processo preso in prestito dalle comunità open source. Prima di introdurre qualsiasi tecnologia significativa, l'autore scrive un RFC: problema, soluzione proposta, alternative, piano di implementazione. Il team discute, vota, accetta o rifiuta. RFC crea trasparenza e previene decisioni architettoniche “silenziose”.

Il Radar Tecnologico (ThoughtWorks Technology Radar) è uno strumento di categorizzazione: Adopt, Trial, Assess, Hold. Il team rivede regolarmente il radar e aggiorna gli stati. Questo aiuta a distinguere il “trendy” dall'“utile” ed evitare l'introduzione di tecnologie non provate in codice critico.

Il principio di coerenza

La qualità più importante dell'architettura è la coerenza. Anche uno strumento non eccellente usato in tutto il progetto è meglio del miglior strumento usato solo in un modulo. La coerenza riduce il carico cognitivo, semplifica l'onboarding e rende il codice prevedibile.

Domande frequenti

In cosa Frankenstein differisce dall'uso di polyglot persistence?

Polyglot persistence è l'uso consapevole di diversi database per diversi compiti (PostgreSQL per transazioni, Redis per cache, Elasticsearch per ricerca). Frankenstein è una miscela caotica senza strategia. La differenza sta nella presenza di una decisione architettonica: polyglot è un piano, Frankenstein è la sua assenza.

Un'architettura a microservizi può trasformarsi in Frankenstein?

, ed è un problema frequente. Quando ogni microservizio usa il proprio linguaggio, il proprio DB, il proprio protocollo e il proprio approccio al deployment senza standard centralizzati — si ottiene un Frankenstein distribuito. Per i microservizi, gli standard comuni sono importanti: protocollo unificato (REST/gRPC), formato log comune, osservabilità centralizzata.

Come convincere il team a non usare una nuova tecnologia?

Non vietare — guidare. Suggerisci all'autore di scrivere un RFC: descrivi perché la soluzione esistente non è adatta, quali alternative sono state considerate, come verrà effettuata la migrazione. Spesso nel processo di scrittura di un RFC, lo sviluppatore stesso capisce che la nuova tecnologia non è necessaria. Se l'RFC è convincente — implementalo, ma con un piano e limitazioni.

Come affrontare Frankenstein in un progetto legacy?

Prima inventario, poi standardizzazione. Non cercare di riscrivere tutto in una volta. Seleziona un livello (es. client HTTP o logging), scegli un unico strumento, scrivi un ADR e migra gradualmente. Il pattern Strangler Fig — sostituisci i vecchi componenti con nuovi uno per uno senza fermare l'applicazione.

Quante tecnologie sono ottimali per un progetto?

Meno sono, meglio è. Idealmente — un linguaggio, un framework, un DB, un metodo di logging. Realisticamente — 2-3 linguaggi (con chiara separazione), 1-2 DB, 1-2 framework. Ogni tecnologia aggiuntiva aumenta il carico cognitivo del team e il costo di manutenzione.

Riepilogo

  • Frankenstein è un anti-pattern in cui il sistema è assemblato da componenti eterogenei incompatibili
  • Cause principali: mancanza di un architetto, fusione di progetti, esperimenti incontrollati
  • Conseguenze — onboarding complesso, comportamento imprevedibile, problemi di sicurezza
  • ADR e RFC sono processi chiave per prevenire l'eclettismo architettonico
  • Il principio “uno strumento per compito” è la base della prevenzione
  • La rifattorizzazione inizia con inventario e standardizzazione dello stack tecnologico
  • La coerenza dell'architettura è più importante del “miglior strumento” per un sotto-compito

Svilupperemo un'applicazione mobile chiavi in mano

IT Sectr crea applicazioni iOS e Android per startup e aziende dal 2017. Ti consulteremo e ti proporremo la soluzione migliore.

Discuti il progetto

Leggi anche