modulo 04 di 24 / Ore 0-20
Moduli 1-8 / Checkpoint 20 ore
Micro-sfida: trova la responsabilità nascosta
Applicare i concetti di responsabilità, coesione, accoppiamento e dipendenze nascoste a un blocco del Registro del laboratorio.
Micro-sfida: trova la responsabilità nascosta
Questa micro-sfida chiude il modulo su responsabilità, coesione e accoppiamento.
Non devi scrivere molto codice. Devi leggere bene.
Il compito è trovare una responsabilità nascosta: un lavoro importante che una funzione sta facendo senza dichiararlo chiaramente.
Una responsabilità nascosta non è semplicemente “codice brutto”. È una responsabilità reale che il nome della funzione non racconta. Per esempio una funzione chiamata cambiaStatoStrumento potrebbe anche leggere la UI, applicare regole di dominio, salvare su localStorage e mostrare messaggi. Il nome dice una cosa, il corpo ne fa sette.
Obiettivo
Allenarti a riconoscere:
- funzioni con troppi motivi per cambiare;
- blocchi poco coesi;
- dipendenze nascoste;
- regole finite nella UI;
- salvataggio mescolato ad altre responsabilità.
Questa abilità viene prima del refactoring. Se non vedi il problema, rischi di spostare codice a caso.
La sfida ha tre risultati:
- una diagnosi scritta;
- una proposta di primo refactoring;
- una verifica da fare dopo la modifica.
Se resta tempo puoi fare il primo refactoring, ma la parte obbligatoria è la diagnosi.
Tempo consigliato
Usa circa 15 minuti:
3 minuti lettura del codice
5 minuti elenco responsabilità e dipendenze
4 minuti scelta della responsabilità nascosta più importante
3 minuti proposta di refactoring e verifica
Se lavori in coppia, uno studente legge il codice e l’altro compila la scheda. Poi vi scambiate i ruoli.
Codice di partenza
Puoi usare un blocco reale del tuo progetto oppure questo esempio:
function cambiaStatoStrumento() {
const id = inputStrumentoId.value;
const nuovoStato = selectNuovoStato.value;
const strumento = strumenti.find((item) => item.id === id);
if (!strumento) {
messaggioElement.textContent = "Strumento non trovato";
return;
}
if (nuovoStato === "in_prestito" && strumento.stato === "guasto") {
messaggioElement.textContent = "Uno strumento guasto non può andare in prestito";
return;
}
strumento.stato = nuovoStato;
localStorage.setItem("strumenti", JSON.stringify(strumenti));
messaggioElement.textContent = "Stato aggiornato";
mostraStrumenti(strumenti);
}
Il codice sembra gestire un cambio stato. In realtà fa di più.
Prima di correggerlo, devi nominarlo. Questa è la disciplina della micro-sfida: non partire dal “sistemiamo tutto”, ma dal “che cosa sta succedendo qui?”.
Come leggere il codice
Non leggere la funzione solo dall’alto verso il basso. Leggila con queste domande:
1. Quale responsabilità promette il nome della funzione?
2. Quali altre responsabilità compaiono nel corpo?
3. Quali dipendenze non sono nei parametri?
4. Quale regola importante è nascosta?
5. Quale cambiamento futuro sarebbe difficile?
6. Quale piccolo refactoring ridurrebbe il problema?
Esempio di lettura:
Nome: cambiaStatoStrumento
Promessa: cambiare lo stato di uno strumento
Sorpresa: la funzione decide anche se un guasto può andare in prestito
Rischio: la regola è bloccata nella UI
La parola chiave è “sorpresa”. Quando il corpo della funzione fa qualcosa che il nome non prepara a trovare, probabilmente c’è una responsabilità nascosta.
Prodotto da consegnare
Qui “consegnare” significa mostrare al docente o al gruppo un risultato verificabile. In questa micro-sfida la consegna principale è una scheda compilata: breve, concreta, leggibile.
Compila questa scheda:
## Responsabilità nascosta
Funzione analizzata:
Responsabilità dichiarata dal nome:
Responsabilità effettive:
- ...
- ...
- ...
Responsabilità nascosta più importante:
Perché è un problema:
Dipendenze nascoste:
- ...
- ...
Possibile primo refactoring:
Comportamento da verificare dopo:
Non limitarti a dire “fa troppe cose”. Devi nominare le cose.
Esempio di risposta
## Responsabilità nascosta
Funzione analizzata:
cambiaStatoStrumento
Responsabilità dichiarata dal nome:
cambiare lo stato di uno strumento
Responsabilità effettive:
- legge input dalla UI
- cerca lo strumento
- applica una regola sul prestito
- modifica lo stato
- salva in localStorage
- mostra un messaggio
- aggiorna la lista
Responsabilità nascosta più importante:
contiene una regola di dominio: uno strumento guasto non può andare in prestito.
Perché è un problema:
la regola resta legata alla UI e non è testabile senza browser.
Dipendenze nascoste:
- inputStrumentoId
- selectNuovoStato
- strumenti
- localStorage
- messaggioElement
- mostraStrumenti
Possibile primo refactoring:
estrarre una funzione puoCambiareStato(strumento, nuovoStato).
Comportamento da verificare dopo:
se lo strumento è guasto e il nuovo stato è in_prestito, il prestito deve essere bloccato.
Questa risposta è buona perché non si ferma a una critica generica. Dice:
- quale funzione è stata analizzata;
- che cosa promette il nome;
- che cosa succede davvero;
- qual è la responsabilità più importante da separare;
- quale rischio produce;
- quale primo passo si può fare.
Vincoli
Durante la sfida:
- non riscrivere tutta la funzione;
- non creare cartelle nuove;
- non introdurre pattern;
- non cambiare comportamento;
- se fai una modifica, deve essere un solo piccolo refactoring.
La cosa importante è la diagnosi.
Un refactoring accettabile in questa sfida è piccolo, per esempio:
function puoCambiareStato(strumento, nuovoStato) {
if (nuovoStato === "in_prestito" && strumento.stato === "guasto") {
return false;
}
return true;
}
Uso nella funzione:
if (!puoCambiareStato(strumento, nuovoStato)) {
messaggioElement.textContent = "Uno strumento guasto non può andare in prestito";
return;
}
Non è ancora il dominio perfetto. Però la regola ha un nome e può essere provata separatamente.
Livelli di riuscita
Usa questa griglia per capire se la consegna è sufficiente:
| Livello | Descrizione |
| --- | --- |
| Da rivedere | Dice solo "la funzione fa troppe cose" senza dettagli |
| Base | Elenca almeno tre responsabilità effettive |
| Buono | Individua una regola o una dipendenza nascosta importante |
| Avanzato | Propone un refactoring piccolo e indica cosa verificare dopo |
Una consegna breve può essere avanzata se è precisa. Una consegna lunga può essere debole se resta generica.
Variante in coppia
Uno studente sceglie una funzione e la passa a un compagno.
Il compagno deve:
- elencare responsabilità;
- trovare dipendenze nascoste;
- proporre un primo refactoring;
- spiegare quale comportamento va verificato dopo la modifica.
Poi si confrontano le risposte.
Se le risposte sono diverse, non è un problema. L’importante è argomentare.
Domande per il confronto:
- Abbiamo individuato la stessa responsabilità nascosta?
- Quale dipendenza ci sembra più pericolosa?
- Quale refactoring è più piccolo?
- Che cosa rischiamo di rompere?
- Quale prova manuale basta per controllare?
Variante con codice reale
Se hai già un Registro funzionante, non usare l’esempio. Scegli una funzione reale tra:
registraStrumento;cercaStrumenti;registraPrestito;chiudiPrestito;apriSegnalazioneGuasto;cambiaStatoStrumento;- una funzione di render che contiene anche logica.
Scegli una funzione che abbia almeno 12 righe o che usi almeno due dipendenze nascoste. Se scegli una funzione troppo semplice, la sfida diventa finta.
Mini-refactoring facoltativo
Se il docente chiede anche una modifica, fai solo questa:
- estrai la responsabilità nascosta in una funzione;
- dai alla funzione un nome chiaro;
- sostituisci il blocco originale con la chiamata alla funzione;
- verifica un caso valido e un caso bloccato.
Esempio:
function puoCambiareStato(strumento, nuovoStato) {
if (nuovoStato === "in_prestito" && strumento.stato === "guasto") {
return false;
}
return true;
}
Poi annota:
Ho estratto la regola sul cambio stato in `puoCambiareStato`.
La funzione principale resta ancora legata alla UI e al salvataggio.
Il comportamento da verificare è il blocco del passaggio da guasto a in_prestito.
Questa nota è importante: mostra che non stai fingendo di aver risolto tutto.
Domande di riflessione
Rispondi per iscritto:
- Quale responsabilità era dichiarata dal nome della funzione?
- Quale responsabilità hai trovato nascosta?
- Perché quella responsabilità dovrebbe stare altrove?
- Quale dipendenza nascosta rende la funzione difficile da testare?
- Quale comportamento devi verificare se fai il refactoring?
Risultato atteso
Alla fine devi avere:
- una scheda compilata;
- una responsabilità nascosta individuata;
- almeno tre dipendenze nascoste;
- una proposta di primo refactoring;
- una verifica da fare dopo il refactoring.
Controllo finale
La micro-sfida è completata quando puoi dire sì a queste domande:
- ho analizzato una funzione reale o realistica;
- ho trovato responsabilità effettive, non solo quella dichiarata dal nome;
- ho individuato almeno una regola nascosta;
- ho individuato dipendenze nascoste;
- ho proposto un refactoring piccolo;
- so quale comportamento controllare dopo la modifica.
Hai completato il Modulo 4. Ora hai strumenti pratici per leggere il codice fragile: responsabilità, coesione, accoppiamento e dipendenze. Nel prossimo modulo useremo questi strumenti per chiarire requisiti, utenti e linguaggio del problema.