modulo 02 di 24 / Ore 0-20

Moduli 1-8 / Checkpoint 20 ore

Leggere il codice fragile e annotare i punti dolorosi

Rileggere il programma fragile con una griglia di osservazione: responsabilità, duplicazioni, regole nella UI, dipendenze nascoste e modifiche rischiose.

20 min Architettura del software

Leggere il codice fragile e annotare i punti dolorosi

Prima di refactorare bisogna leggere.

Molti studenti vedono un codice disordinato e vogliono riscriverlo da zero. È comprensibile, ma rischioso. In un progetto reale raramente puoi buttare tutto. Devi prima capire:

  • cosa funziona;
  • cosa è fragile;
  • quali regole sono importanti;
  • quali modifiche fanno paura;
  • dove intervenire per primi.

Questa lezione è una piccola revisione tecnica del codice fragile.

Obiettivo della lezione

Alla fine devi avere:

  • una lettura ordinata di main.js;
  • esempi concreti di responsabilità mescolate;
  • almeno una regola importante individuata nella UI;
  • duplicazioni annotate;
  • dipendenze nascoste riconosciute;
  • modifiche rischiose elencate;
  • un file note-architettura.md con le osservazioni principali.

Non stiamo ancora cambiando il codice. Stiamo preparando un refactoring sensato.

Non cercare subito la soluzione

Per ora non devi spostare file o inventare livelli.

Devi annotare.

Una buona annotazione trasforma:

Questo file è confuso.

in:

L'event listener del prestito legge input, applica regole di dominio,
modifica dati, salva in localStorage e aggiorna la UI.

La seconda frase è utile. La prima no.

Una revisione tecnica non serve a sfogarsi sul codice. Serve a rendere visibili i problemi in modo abbastanza preciso da poterli risolvere.

Griglia di osservazione

Usa questa griglia:

1. Responsabilità mescolate
2. Regole importanti nella UI
3. Duplicazione
4. Dipendenze nascoste
5. Dati modificati direttamente
6. Errori poco chiari
7. Codice difficile da testare
8. Modifiche che fanno paura

Leggi main.js e compila almeno un esempio per ogni punto.

Se non trovi un esempio per una voce, scrivi non trovato per ora. Anche questa è un’informazione utile.

Responsabilità mescolate

Cerca funzioni o event listener che fanno più lavori.

Esempio:

bottonePresta.addEventListener("click", () => {
  const id = inputStrumentoId.value;
  const studente = inputStudente.value;
  const strumento = strumenti.find((item) => item.id === id);

  if (!strumento) {
    messaggioElement.textContent = "Strumento non trovato";
    return;
  }

  if (strumento.stato === "guasto") {
    messaggioElement.textContent = "Uno strumento guasto non può essere prestato";
    return;
  }

  strumento.stato = "in_prestito";
  localStorage.setItem("strumenti", JSON.stringify(strumenti));
  mostraStrumenti(strumenti);
});

Annotazione:

Responsabilità mescolate:
  - legge input dalla UI
  - cerca dati
  - applica regole
  - modifica stato
  - salva dati
  - aggiorna UI

Questa annotazione è già una mappa del futuro refactoring.

Regole importanti nella UI

Cerca frasi che descrivono comportamenti sempre validi.

Esempio:

if (strumento.stato === "guasto") {
  messaggioElement.textContent = "Uno strumento guasto non può essere prestato";
  return;
}

Annotazione:

Regola di dominio dentro la UI:
  uno strumento guasto non può essere prestato.

Questa regola dovrà uscire dall’event listener, perché deve valere anche se un giorno usiamo una CLI, un test automatico o una UI diversa.

Duplicazione

Cerca valori ripetuti:

"disponibile"
"in_prestito"
"guasto"
"in_manutenzione"

Se le stesse stringhe compaiono in HTML, JavaScript, messaggi e filtri, il rischio di incoerenza aumenta.

Annotazione:

Duplicazione:
  gli stati sono ripetuti in select HTML, controlli JS e messaggi.

Non tutte le duplicazioni hanno lo stesso peso. Questa è importante perché riguarda il significato del sistema.

Dipendenze nascoste

Una dipendenza è nascosta quando una funzione usa qualcosa che non riceve come parametro e che non dichiara chiaramente.

Esempio:

function aggiornaRisultati() {
  const testo = inputRicerca.value.toLowerCase();
  const stato = filtroStato.value;
  const risultati = strumenti.filter(/* ... */);
  mostraStrumenti(risultati);
}

Annotazione:

Dipendenze nascoste:
  aggiornaRisultati dipende da inputRicerca, filtroStato,
  strumenti globali e mostraStrumenti.

Questo rende la funzione difficile da testare. Per provarla devi ricostruire pezzi di pagina, stato globale e funzioni esterne.

Dati modificati direttamente

Cerca modifiche dirette:

strumento.stato = nuovoStato;

Annotazione:

Dato modificato direttamente:
  la UI può impostare qualunque stato senza passare da una regola.

Non sempre modificare un oggetto è sbagliato. Qui il problema è che non c’è controllo sul significato della modifica.

Cambiare stato non è solo assegnare una stringa. Nel Registro può significare aprire un prestito, chiuderlo, segnalare un guasto o mettere uno strumento in manutenzione.

Errori poco chiari

Cerca punti in cui il codice presuppone che qualcosa esista.

Esempio fragile:

const strumento = strumenti.find((item) => item.id === id);
strumento.stato = "guasto";

Se strumento non esiste, potresti ottenere:

Cannot set properties of undefined

Annotazione:

Errore poco chiaro:
  se manca lo strumento, l'utente potrebbe vedere un errore tecnico
  invece di "Strumento non trovato".

Un errore tecnico può essere utile allo sviluppatore, ma non basta per l’utente.

Codice difficile da testare

Una regola è difficile da testare se per verificarla devi:

  • creare HTML;
  • simulare click;
  • leggere messaggi nel DOM;
  • preparare localStorage;
  • ricostruire stato globale.

Annotazione:

Regola difficile da testare:
  per verificare che uno strumento guasto non venga prestato
  devo passare dal bottone.

In futuro vogliamo testare la regola senza browser.

Modifiche che fanno paura

Scrivi una lista di modifiche che oggi sarebbero rischiose.

Esempi:

- aggiungere un nuovo stato
- cambiare localStorage con file JSON
- mostrare la stessa logica in una CLI
- tradurre i messaggi
- testare i casi d'uso senza browser
- impedire passaggi di stato non validi
- distinguere errore utente ed errore tecnico

Questa lista guiderà il refactoring.

Una modifica che “fa paura” è una modifica che potrebbe rompere parti lontane del codice. L’architettura serve proprio a ridurre questa paura.

Creare note-architettura.md

Crea un file nel progetto:

note-architettura.md

Dentro scrivi:

# Note architetturali iniziali

## Responsabilità mescolate

## Regole nella UI

## Duplicazioni

## Dipendenze nascoste

## Dati modificati direttamente

## Errori poco chiari

## Codice difficile da testare

## Modifiche rischiose

Compila ogni sezione con almeno un esempio reale dal tuo codice.

Non scrivere definizioni generiche. Scrivi osservazioni collegate a righe, funzioni o comportamenti del Registro.

Esempio di nota buona

Nota debole:

Il codice è brutto.

Nota utile:

Nel click di "Registra prestito" ci sono input della UI, regola su strumento guasto,
modifica dello stato, salvataggio in localStorage e messaggio utente.
Se voglio testare la regola devo passare dal browser.

La nota utile dice:

  • dove sta il problema;
  • quali responsabilità contiene;
  • perché rende difficile una modifica.

Micro-sfida

Scegli una sola riga di codice e prova a spiegare perché è fragile.

Esempio:

strumento.stato = nuovoStato;

Risposta possibile:

Questa riga è fragile perché permette alla UI di assegnare qualunque stato.
Non controlla se il passaggio ha senso e non registra perché lo stato cambia.

Vincolo: la spiegazione deve contenere almeno una conseguenza pratica, non solo un giudizio.

Prodotto da ottenere

Alla fine della lezione devi avere:

  • file note-architettura.md;
  • almeno una nota per ogni voce della griglia;
  • lista di modifiche rischiose;
  • una riga fragile spiegata con una conseguenza pratica;
  • nessun refactoring ancora applicato.

Domande di comprensione

Rispondi per iscritto:

  • Perché non conviene riscrivere subito tutto?
  • Che differenza c’è tra “codice confuso” e una nota tecnica utile?
  • Quale regola importante hai trovato nella UI?
  • Quale funzione o event listener ha più dipendenze nascoste?
  • Quale modifica ti sembra più rischiosa e perché?

Controllo finale

La lezione è completata quando puoi dire sì a queste domande:

  • ho letto il codice prima di modificarlo;
  • ho annotato responsabilità mescolate;
  • ho individuato almeno una regola nella UI;
  • ho trovato duplicazioni di stati o messaggi;
  • ho riconosciuto dipendenze nascoste;
  • ho scritto una lista di modifiche rischiose;
  • so spiegare una fragilità con un esempio preciso.

Nel prossimo passo faremo una prima retrospettiva. Non cambieremo ancora tutto: decideremo cosa conservare, cosa fa paura e quali saranno i prossimi passi.