modulo 02 di 24 / Ore 0-20
Moduli 1-8 / Checkpoint 20 ore
Costruire il registro fragile in un solo file
Costruire intenzionalmente una prima versione fragile del Registro del laboratorio, con dati, visualizzazione e prime azioni concentrate in un unico file.
Costruire il registro fragile in un solo file
In questa lezione faremo una cosa che di solito si evita: scriveremo codice fragile.
Non perché sia un buon punto di arrivo, ma perché è un ottimo punto di partenza didattico. Se introduciamo subito cartelle, livelli e astrazioni, l’architettura sembra una regola imposta dall’esterno. Se invece partiamo da un programma che funziona ma diventa scomodo, la separazione delle responsabilità diventa una risposta concreta.
Il compito di questa lezione è costruire una prima versione del Registro del laboratorio in un solo file JavaScript.
Obiettivo della lezione
Alla fine avrai:
- una lista di strumenti in memoria;
- una funzione che mostra gli strumenti nella pagina;
- un modo semplice per registrare un prestito;
- un modo semplice per segnare uno strumento come guasto;
- messaggi minimi per l’utente;
- codice funzionante ma volutamente poco organizzato;
- prime osservazioni su cosa rende fragile il programma.
Non correggere subito la struttura. Per ora devi sentire il problema.
Punto di partenza
Parti dalla struttura creata nel modulo precedente:
registro-laboratorio/
README.md
index.html
src/
main.js
datiIniziali.js
In questa lezione useremo soprattutto src/main.js.
Se hai già separato i dati in datiIniziali.js, puoi anche importarli. Però qui faremo una scelta precisa: porteremo molte responsabilità dentro main.js per vedere cosa succede quando il progetto cresce senza confini.
Perché costruire qualcosa di fragile
Un errore didattico comune è partire subito dalla soluzione ordinata.
Il docente mostra cartelle come:
domain/
application/
infrastructure/
presentation/
e lo studente si chiede:
ma perché servono tutte queste cose?
Questa lezione risponde con un’esperienza pratica: prima costruiamo il programma diretto, poi osserviamo dove diventa scomodo.
Il codice fragile non è un fallimento. È materiale di studio.
HTML minimo
In index.html prepara alcuni elementi:
<h1>Registro del laboratorio scolastico</h1>
<section>
<h2>Strumenti</h2>
<div id="strumenti"></div>
</section>
<section>
<h2>Azioni rapide</h2>
<label>
ID strumento
<input id="strumento-id" />
</label>
<label>
Nome studente
<input id="studente" />
</label>
<button id="presta">Registra prestito</button>
<button id="guasto">Segna guasto</button>
</section>
<p id="messaggio"></p>
<script type="module" src="./src/main.js"></script>
La pagina è minima. Non stiamo progettando l’interfaccia finale. Ci serve solo un bordo visibile per provare le azioni.
Prima versione fragile di main.js
Scrivi una versione diretta, concentrata in un solo file:
let strumenti = [
{
id: "str-001",
nome: "Notebook Lenovo 01",
categoria: "notebook",
stato: "disponibile",
},
{
id: "str-002",
nome: "Kit Arduino Base",
categoria: "elettronica",
stato: "disponibile",
},
{
id: "str-003",
nome: "Tablet laboratorio 03",
categoria: "tablet",
stato: "guasto",
},
];
let prestiti = [];
const strumentiElement = document.querySelector("#strumenti");
const messaggioElement = document.querySelector("#messaggio");
const inputStrumentoId = document.querySelector("#strumento-id");
const inputStudente = document.querySelector("#studente");
const bottonePresta = document.querySelector("#presta");
const bottoneGuasto = document.querySelector("#guasto");
function mostraStrumenti() {
strumentiElement.innerHTML = `
<ul>
${strumenti
.map(
(strumento) => `
<li>
<strong>${strumento.nome}</strong>
<span>${strumento.categoria}</span>
<span>${strumento.stato}</span>
<code>${strumento.id}</code>
</li>
`,
)
.join("")}
</ul>
`;
}
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 (!studente) {
messaggioElement.textContent = "Inserisci il nome dello studente";
return;
}
if (strumento.stato === "guasto") {
messaggioElement.textContent = "Uno strumento guasto non può essere prestato";
return;
}
if (strumento.stato === "in_prestito") {
messaggioElement.textContent = "Lo strumento è già in prestito";
return;
}
strumento.stato = "in_prestito";
prestiti.push({
id: `pre-${Date.now()}`,
strumentoId: strumento.id,
studente,
aperto: true,
});
messaggioElement.textContent = "Prestito registrato";
mostraStrumenti();
});
bottoneGuasto.addEventListener("click", () => {
const id = inputStrumentoId.value;
const strumento = strumenti.find((item) => item.id === id);
if (!strumento) {
messaggioElement.textContent = "Strumento non trovato";
return;
}
strumento.stato = "guasto";
messaggioElement.textContent = "Strumento segnato come guasto";
mostraStrumenti();
});
mostraStrumenti();
Questo codice funziona, ma contiene già diversi segnali interessanti.
Prova il comportamento
Avvia la pagina e prova questi casi:
- presta
str-001a uno studente; - prova a prestare
str-001una seconda volta; - prova a prestare
str-003, che è guasto; - segna
str-002come guasto; - prova a prestare
str-002; - prova a premere
Registra prestitosenza scrivere il nome dello studente; - prova a inserire un ID che non esiste.
Annota per ogni caso:
- azione fatta;
- messaggio mostrato;
- stato dello strumento prima;
- stato dello strumento dopo;
- punto del codice che ha deciso il risultato.
Questa tabella di osservazione sarà utile nelle lezioni successive.
Perché questo codice è fragile
L’event listener del bottone Registra prestito fa troppe cose:
- legge input dalla pagina;
- cerca uno strumento;
- controlla se lo strumento esiste;
- controlla se lo studente è stato inserito;
- applica una regola di dominio;
- cambia lo stato dello strumento;
- crea un prestito;
- aggiorna un messaggio utente;
- aggiorna la lista nella pagina.
Tutte queste operazioni sono nello stesso punto.
Per ora non le separiamo. Le osserviamo.
La fragilità non è solo disordine estetico
Il problema non è che il file è “brutto”.
Il problema è che ogni modifica rischia di toccare troppe cose insieme.
Esempio: vuoi cambiare il messaggio mostrato all’utente. Devi entrare nello stesso blocco in cui ci sono anche regole di prestito e modifica dello stato.
Esempio: vuoi testare la regola “uno strumento guasto non può essere prestato”. La regola sta dentro un click del browser, quindi non è semplice provarla senza pagina.
Esempio: vuoi salvare i dati in localStorage. Dove lo aggiungi? Probabilmente dentro gli stessi event listener. Il file crescerebbe ancora.
Questa è fragilità: il programma funziona, ma non invita a cambiare con sicurezza.
Cosa succede se cambia una regola
Immagina che arrivi una nuova regola:
uno strumento in manutenzione non può essere prestato
Dove la metteresti?
Probabilmente dentro l’event listener del bottone Registra prestito:
if (strumento.stato === "in_manutenzione") {
messaggioElement.textContent = "Lo strumento è in manutenzione";
return;
}
Funziona, ma la UI sta diventando il posto in cui vivono le regole.
Questo è uno dei problemi centrali del corso.
Cosa succede se cambia la UI
Immagina di sostituire la pagina web con una CLI, oppure di creare un test automatico.
Dove sta la regola?
nel click del bottone
Questo significa che per verificarla devi passare dalla UI.
Nel corso sposteremo questa regola nel dominio. Ma non ancora. Prima dobbiamo imparare a riconoscerla.
Cosa succede se cambia il salvataggio
Per ora strumenti e prestiti vivono in memoria. Se ricarichi la pagina, i cambiamenti spariscono.
Se volessi salvare tutto in localStorage, potresti aggiungere qualcosa del genere dentro gli event listener:
localStorage.setItem("strumenti", JSON.stringify(strumenti));
localStorage.setItem("prestiti", JSON.stringify(prestiti));
Anche questo funzionerebbe. Ma ora il click del bottone conterrebbe:
- lettura input;
- regole;
- modifica dati;
- messaggi;
- aggiornamento UI;
- salvataggio tecnico.
Il punto non è vietare questa soluzione. Il punto è vedere quanto velocemente cresce il miscuglio.
Attività guidata
Implementa il codice fragile e compila una piccola tabella nei tuoi appunti:
| Caso provato | Risultato | Dove viene deciso nel codice? |
|---|---|---|
Presto str-001 | diventa in_prestito | event listener presta |
Presto str-003 | messaggio di errore | controllo su stato === "guasto" |
| ID inesistente | messaggio di errore | controllo !strumento |
La colonna più importante è l’ultima. Serve a collegare comportamento e posizione del codice.
Micro-sfida
Aggiungi un pulsante Rendi disponibile.
Vincoli:
- scrivi il codice nello stesso stile fragile;
- non creare ancora cartelle nuove;
- non introdurre una funzione di dominio;
- aggiorna la lista dopo il click;
- mostra un messaggio all’utente.
Risultato atteso: lo strumento torna allo stato disponibile.
Domanda da annotare: quante righe hai dovuto copiare o adattare da altri event listener?
Prodotto da ottenere
Alla fine della lezione devi avere:
- pagina che mostra gli strumenti;
- input per ID strumento e nome studente;
- bottone per registrare un prestito;
- bottone per segnare uno strumento come guasto;
- eventuale bottone
Rendi disponibiledella micro-sfida; - messaggi minimi per l’utente;
- lista di almeno tre responsabilità mescolate in
main.js; - tabella di osservazione con i casi provati.
Domande di comprensione
Rispondi per iscritto:
- Perché in questa lezione scriviamo intenzionalmente codice fragile?
- Quali responsabilità sono mescolate nell’event listener del prestito?
- Dove si trova la regola “uno strumento guasto non può essere prestato”?
- Perché questa posizione renderà più difficile scrivere test?
- Che cosa rischia di succedere quando aggiungeremo il salvataggio?
Controllo finale
La lezione è completata quando puoi dire sì a queste domande:
- il Registro mostra gli strumenti;
- puoi registrare un prestito;
- uno strumento guasto non viene prestato;
- uno strumento già in prestito non viene prestato di nuovo;
- puoi segnare uno strumento come guasto;
- hai scritto codice funzionante ma chiaramente fragile;
- sai indicare almeno tre responsabilità mescolate nello stesso punto.
Nel prossimo passo guarderemo proprio questo miscuglio: dati, eventi, regole e salvataggio nello stesso codice.