modulo 14 di 24 / Ore 21-40

Moduli 9-16 / Checkpoint 40 ore

Riconoscere un God Service

Capire cos'è un God Service, riconoscerlo nel Registro del laboratorio dai suoi sintomi, e capire perché renderlo più difficile da testare, modificare e capire.

25 min Architettura del software

Riconoscere un God Service

Questa lezione appartiene al Modulo 14 — Refactoring: migliorare senza ricominciare.

Cos’è un God Service

Un God Service (o God Class, God Object) è un modulo, file o funzione che sa troppe cose e fa troppe cose. Il nome viene dall’idea che “sa tutto e controlla tutto” — come un dio nel sistema.

I sintomi concreti:

  • il file ha centinaia di righe
  • la funzione principale ha decine di parametri o accede a decine di variabili
  • toccarlo rompe qualcosa di inaspettato in un’altra parte del sistema
  • è impossibile testarlo senza portarsi dietro tutta la dipendenza del progetto
  • ogni nuova funzionalità viene aggiunta lì “perché è il posto più comodo”

Come nasce nel Registro

Il God Service nasce dalla convenienza. Invece di separare responsabilità, si mette tutto in un posto:

// ❌ God Service nel Registro — un file che fa tutto
// registroCompleto.js

let strumenti = [];
let prestiti = [];

function registraStrumento(nome, categoria) {
  // Valida input
  if (!nome || nome.trim().length < 2) {
    alert("Nome non valido");
    return;
  }
  // Crea strumento
  const strumento = { id: crypto.randomUUID(), nome: nome.trim(), categoria, stato: "disponibile" };
  // Salva
  strumenti.push(strumento);
  localStorage.setItem("strumenti", JSON.stringify(strumenti));
  // Aggiorna UI
  document.getElementById("lista").innerHTML = strumenti.map(s => `<li>${s.nome}</li>`).join("");
}

function registraPrestito(strumentoId, persona) {
  const strumento = strumenti.find(s => s.id === strumentoId);
  if (!strumento) { alert("Non trovato"); return; }
  if (strumento.stato !== "disponibile") { alert("Non disponibile"); return; }
  // Crea prestito
  const prestito = { id: crypto.randomUUID(), strumentoId, persona, apertoIl: new Date().toISOString() };
  // Salva due cose insieme
  prestiti.push(prestito);
  strumento.stato = "in_prestito";
  localStorage.setItem("prestiti", JSON.stringify(prestiti));
  localStorage.setItem("strumenti", JSON.stringify(strumenti));
  // Aggiorna UI
  document.getElementById("lista").innerHTML = strumenti.map(s => `<li>${s.nome} - ${s.stato}</li>`).join("");
  alert("Prestito registrato");
}

function segnalaGuasto(strumentoId, descrizione) { /* ... */ }
function chiudiPrestito(prestitoId) { /* ... */ }
function cercaStrumenti(query) { /* ... */ }
// ... altre 200 righe ...

Questo file è il God Service del Registro: conosce gli strumenti, i prestiti, localStorage, il DOM, le regole di validazione, i messaggi per l’utente. È impossibile testare registraStrumento senza avere il DOM aperto.

I quattro sintomi diagnostici

Sintomo 1: troppe dipendenze

// Quante cose usa questa funzione?
function registraPrestito(strumentoId, persona) {
  const strumento = strumenti.find(...); // ← array globale
  // ...
  localStorage.setItem(...); // ← side effect
  document.getElementById(...); // ← DOM
  alert(...); // ← UI
}
// Risposta: 4 dipendenze diverse in una funzione. Troppo.

Sintomo 2: tanti “motivi per cambiare”

Una funzione con un’unica responsabilità cambia solo per un motivo. Il God Service cambia per molti motivi:

  • cambia se si modifica la regola di validazione del nome
  • cambia se si modifica il formato di localStorage
  • cambia se si modifica il testo del messaggio per l’utente
  • cambia se si modifica la struttura dell’HTML
  • cambia se si aggiunge un nuovo campo allo strumento

Regola pratica: se riesci a elencare più di due motivi per cui la funzione potrebbe cambiare, è un segnale di God Service.

Sintomo 3: impossibile da testare in isolamento

// Questo test non funziona senza un browser completo
test("registra uno strumento", () => {
  registraStrumento("Trapano", "Elettrico"); // ← usa document, localStorage, alert
  // Non si può testare senza DOM e localStorage
});

// Confronto con funzione non-God:
test("creaStrumento valida il nome", () => {
  expect(() => creaStrumento({ id: "s1", nome: "T" })).toThrow("NOME_NON_VALIDO");
  // Funziona senza DOM, senza localStorage
});

Sintomo 4: ogni modifica richiede di capire tutto il contesto

Se per modificare il testo di un messaggio di errore devi leggere 200 righe di codice per capire dove farlo — il modulo è diventato un God Service.

Come si decostruisce un God Service

Non si riscrive da zero — si estrae responsabilità una alla volta:

Passo 1: identifica le responsabilità nel God Service
  - Validazione input → Application o Domain
  - Regole del laboratorio → Domain
  - Salvataggio → Infrastructure
  - Aggiornamento UI → Presentation
  - Messaggi per l'utente → Presentation

Passo 2: scrivi un test per il comportamento attuale

Passo 3: estrai una responsabilità in un file separato

Passo 4: verifica che il comportamento sia invariato

Passo 5: ripeti per la prossima responsabilità

Riconoscere un God Service nel tuo progetto

Usa questa checklist diagnostica su ogni file del Registro:

□ Il file ha più di 100 righe?
□ Le funzioni nel file usano più di 3 dipendenze diverse?
□ Ci sono più di 5 "motivi per cambiare" per il file?
□ È impossibile testare una funzione senza DOM o localStorage?
□ Ogni nuova funzionalità del Registro viene aggiunta qui?

Se 3 o più risposte sono "sì" → God Service da decostruire.

Procedura guidata

  1. Apri ogni file del Registro — quante righe ha? Quante responsabilità riconosci?
  2. Per il file più grande: elenca le responsabilità presenti.
  3. Conta i motivi per cui il file potrebbe cambiare.
  4. Se è un God Service: scrivi una verifica del comportamento attuale.
  5. Estrai una responsabilità nel livello corretto.
  6. Verifica che il comportamento sia invariato.

Attività in classe

## Analisi God Service

File analizzato:

Righe totali:

Responsabilità presenti (elenca):

Dipendenze esterne usate:

Motivi per cui potrebbe cambiare:

È un God Service (sì/no con motivazione):

Se sì — responsabilità da estrarre per prima:
  - Responsabilità: 
  - Livello corretto: 
  - Verifica prima dell'estrazione:

Spiegazione guidata per studiare

Il God Service è l’antipattern opposto alla separazione dei livelli. Invece di avere quattro livelli con responsabilità chiare, si ha un unico posto che conosce tutto e decide tutto.

Il punto centrale è: il God Service nasce dalla convenienza ma diventa una prigione. È conveniente aggiungere una nuova funzione al file che “già fa tutto”. Diventa una prigione quando ogni modifica diventa rischiosa perché non si sa cosa potrebbe rompere.

Il rischio tipico è non riconoscerlo finché non è troppo tardi — quando il file ha 500 righe e toccare una funzione spaventa tutti. Per questo vale la pena diagnosticare presto, prima che il God Service si consolidi.

Passo per passo nel progetto

  1. Apri il file più grande del tuo progetto.
  2. Elenca le responsabilità che contiene (almeno tre righe descrittive).
  3. Conta quante volte usa localStorage, document, variabili globali, regole di dominio.
  4. Se trova più di 2-3 responsabilità mischiate: è un God Service.
  5. Scegli la responsabilità più isolata da estrarre per prima.

Esempio da leggere lentamente

// Diagnostica rapida su un file

// PRIMA (God Service):
// - usa strumenti[] globale
// - usa prestiti[] globale
// - chiama localStorage
// - accede al DOM
// - mostra alert
// - implementa regole di dominio
// → 6 responsabilità diverse → God Service confermato

// DOPO (responsabilità separate):
// domain/strumento.js → solo regole su strumenti
// application/registraPrestito.js → solo coordinamento
// infrastructure/archivioLocalStorage.js → solo persistenza
// presentation/ui.js → solo DOM e messaggi
// → ogni file ha 1-2 responsabilità → no God Service

Prova di comprensione

  • Hai trovato un God Service nel tuo progetto? Come l’hai riconosciuto?
  • Quante responsabilità ha? Riesci a elencarle tutte?
  • Quale responsabilità estraggeresti per prima? Perché quella?

Errori da evitare

  • estrarre responsabilità senza una verifica del comportamento attuale;
  • riscrivere tutto il God Service in una sola sessione — è troppo rischioso;
  • confondere “file grande” con God Service — un file può essere grande e avere una responsabilità chiara;
  • non documentare le responsabilità trovate prima di iniziare l’estrazione.

Prodotto da consegnare

Può essere:

  • la scheda diagnostica compilata per il file più grande del progetto;
  • l’elenco delle responsabilità del God Service trovato con piano di estrazione;
  • una prima estrazione applicata con verifica del comportamento.

Checklist di chiusura

  • Ho analizzato ogni file del progetto con la checklist diagnostica
  • Ho identificato se esiste un God Service (e quale)
  • Ho elencato le responsabilità presenti nel God Service
  • Ho scelto la responsabilità da estrarre per prima
  • (Se applicabile) Ho estratto una responsabilità con verifica del comportamento

Domande per la revisione

  • Il file più grande del tuo progetto è un God Service? Quante responsabilità ha?
  • Dopo l’estrazione, quante responsabilità restano nel file originale?
  • Come eviteresti di creare un nuovo God Service in futuro?

Risultato atteso

Alla fine lo studente deve saper dire:

Ho analizzato [file] — ha [N] responsabilità diverse: [lista].
È / non è un God Service perché [motivazione].
[Se è un God Service] La prima responsabilità da estrarre è [X] nel livello [Y].
Ho / non ho eseguito l'estrazione — il comportamento è rimasto invariato.

Se questa spiegazione non è possibile, la lezione non è ancora davvero conclusa.