modulo 21 di 24 / Ore 41-60

Moduli 17-24 / Checkpoint 60 ore

Prompt per trovare responsabilità eccessive

Come formulare prompt per chiedere a un AI di trovare funzioni o file con troppe responsabilità nel Registro, con esempi di prompt e criteri di valutazione delle segnalazioni.

25 min Architettura del software

Prompt per trovare responsabilità eccessive

Questa lezione appartiene al Modulo 21 — Usare l’AI come revisore.

Obiettivo della lezione

Formulare prompt che producono segnalazioni concrete di funzioni o file con troppe responsabilità nel Registro — con la spiegazione del perché è un problema e cosa si può fare.

Perché serve nel percorso

Una funzione con troppe responsabilità è difficile da testare, da modificare e da capire. Riconoscerla da soli è complicato perché di solito si costruisce gradualmente — ogni aggiunta sembra piccola. Un AI con il giusto prompt può vedere il problema dall’esterno.

Nel Registro del laboratorio

Prompt per trovare responsabilità eccessive:

Questo è il file src/application/registraPrestito.js del mio progetto
"Registro del laboratorio scolastico" (JavaScript modulare, browser-only, localStorage).

Il principio di singola responsabilità dice che una funzione dovrebbe avere
un solo motivo per cambiare.

Analizza questo file e dimmi:
1. Quante responsabilità distinte ha la funzione registraPrestito?
2. Elenca ogni responsabilità con una frase ("si occupa di...")
3. Qual è la responsabilità che appartiene a un livello diverso?
4. Qual è il refactoring minimo per separare la responsabilità più fuori posto?

[incolla il contenuto del file]

Esempio di risposta utile:

La funzione registraPrestito ha 4 responsabilità distinte:

1. Si occupa di leggere lo strumento da localStorage (→ infrastruttura, non application)
2. Si occupa di verificare se lo strumento è prestabile (→ dominio)
3. Si occupa di generare l'ID del prestito (→ dominio o application)
4. Si occupa di salvare il prestito in localStorage (→ infrastruttura, non application)

Responsabilità più fuori posto: la lettura e la scrittura diretta su localStorage.
Un caso d'uso non dovrebbe conoscere localStorage — dovrebbe ricevere l'archivio come dipendenza.

Refactoring minimo: cambia la firma a registraPrestito(dati, archivioStrumenti, archivioPrestiti)
e rimuovi le chiamate dirette a localStorage dalla funzione.

Prompt per trovare file con troppe responsabilità:

Questi sono i file di src/presentation/ del Registro del laboratorio scolastico.

Un file di presentazione dovrebbe solo: leggere input dell'utente, chiamare casi d'uso,
mostrare risultati. Non dovrebbe contenere regole di dominio o accesso diretto a localStorage.

Per ogni file in src/presentation/ dimmi:
- contiene regole di dominio? (es. controlla se uno strumento è disponibile)
- accede direttamente a localStorage?
- mescola la logica di display con la logica di business?

Elenca le righe specifiche che violano questi principi.

Procedura guidata

  1. Scegli un file che sospetti abbia troppe responsabilità (spesso quello più lungo).
  2. Scrivi il prompt con il contenuto del file e il principio da verificare.
  3. Ricevi la lista di responsabilità distinte.
  4. Per ogni responsabilità: identifica il livello corretto nel Registro.
  5. Scegli il refactoring minimo e pianificalo in passi.

Attività in classe

Analizza questo file con il prompt e compila la scheda:

// src/presentation/paginaPrestiti.js (versione fragile per l'esercizio)
function handleSubmitPrestito(event) {
  event.preventDefault();
  const strumentoId = form.elements["strumento"].value;
  const studenteId = form.elements["studente"].value;

  // Regola di dominio nella UI
  const strumenti = JSON.parse(localStorage.getItem("registro_strumenti") || "[]");
  const strumento = strumenti.find(s => s.id === strumentoId);
  if (!strumento || strumento.stato !== "disponibile") {
    alert("Strumento non disponibile");
    return;
  }

  // Logica di salvataggio nella UI
  strumento.stato = "in_prestito";
  localStorage.setItem("registro_strumenti", JSON.stringify(strumenti));

  const prestiti = JSON.parse(localStorage.getItem("registro_prestiti") || "[]");
  prestiti.push({ id: crypto.randomUUID(), strumentoId, studenteId, apertura: new Date() });
  localStorage.setItem("registro_prestiti", JSON.stringify(prestiti));

  alert("Prestito registrato");
}
## Responsabilità trovate nel file

Responsabilità 1:
Livello corretto:

Responsabilità 2:
Livello corretto:

Responsabilità 3:
Livello corretto:

Refactoring minimo proposto:

Spiegazione guidata per studiare

La responsabilità eccessiva si riconosce con questa domanda: “quante ragioni diverse potrebbero portare a modificare questa funzione?”

Per handleSubmitPrestito nell’esempio:

  • se cambia la regola su quando uno strumento è prestabile → devo modificare questa funzione;
  • se cambia il formato di salvataggio in localStorage → devo modificare questa funzione;
  • se cambia la struttura del form HTML → devo modificare questa funzione;
  • se cambia il formato dell’ID del prestito → devo modificare questa funzione.

Quattro motivi per cambiare = quattro responsabilità diverse in una sola funzione.

Un prompt AI efficace chiede esplicitamente di contare i motivi di cambiamento:

Per ogni funzione nel file, conta quante ragioni distinte potrebbero portare a modificarla.
Una funzione con più di 2 ragioni ha probabilmente troppe responsabilità.
Elenca le ragioni per le funzioni con più di 2.

Come valutare la risposta:

L’AI tende a essere generosa nel trovare “responsabilità” — a volte split troppo aggressivo. Il criterio pratico è: “separare questa responsabilità rende il progetto più facile da testare e da modificare?” Se la risposta è sì, vale la pena. Se è no (separazione artificiale che non cambia nulla di pratico), ignora il suggerimento.

Passo per passo nel progetto

  1. Usa wc -l src/application/*.js per trovare il file più lungo.
  2. Leggi il file e conta le responsabilità.
  3. Invia il prompt all’AI con il contenuto del file.
  4. Confronta la tua analisi con quella dell’AI.
  5. Scegli le responsabilità da separare (priorità: quelle che rendono il codice più testabile).
  6. Pianifica il refactoring in passi piccoli.

Prova di comprensione

  • Come si conta il numero di responsabilità di una funzione?
  • Qual è la differenza tra “separazione utile” e “separazione artificiale”?
  • Un file da 200 righe ha necessariamente troppe responsabilità?
  • Come si verifica che una responsabilità appartiene al livello sbagliato?

Errori da evitare

  • separare responsabilità che cambiano sempre insieme — non ha senso separarle;
  • creare file di 5 righe ciascuno per “rispettare” il principio — overengineering;
  • accettare tutte le segnalazioni dell’AI senza valutare il costo del refactoring;
  • non verificare sul codice reale se la segnalazione è accurata.

Prodotto da consegnare

Il prompt usato, la lista di responsabilità trovate (tua + AI), la valutazione comparata e il piano di refactoring per la responsabilità più fuori posto.

Checklist di chiusura

  • il prompt specifica il principio da verificare (singola responsabilità)
  • la lista di responsabilità è basata su “motivi per cambiare”, non su “cose che fa”
  • ogni responsabilità è associata al livello corretto del Registro
  • il refactoring pianificato è in passi piccoli con verifica
  • le segnalazioni dell’AI sono state confrontate con l’analisi manuale

Risultato atteso

Ho analizzato handleSubmitPrestito — ha 4 responsabilità (regola, lettura localStorage,
scrittura localStorage, generazione ID).
Il prompt AI ha confermato le stesse 4 responsabilità.
Ho pianificato 3 passi di refactoring: estrarre il caso d'uso, iniettare l'archivio, spostare la regola nel dominio.
Ho eseguito il primo passo e i test passano.