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.
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
- Apri ogni file del Registro — quante righe ha? Quante responsabilità riconosci?
- Per il file più grande: elenca le responsabilità presenti.
- Conta i motivi per cui il file potrebbe cambiare.
- Se è un God Service: scrivi una verifica del comportamento attuale.
- Estrai una responsabilità nel livello corretto.
- 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
- Apri il file più grande del tuo progetto.
- Elenca le responsabilità che contiene (almeno tre righe descrittive).
- Conta quante volte usa
localStorage,document, variabili globali, regole di dominio. - Se trova più di 2-3 responsabilità mischiate: è un God Service.
- 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.