modulo 10 di 24 / Ore 21-40
Moduli 9-16 / Checkpoint 40 ore
Salvare e leggere strumenti da localStorage
Implementare un ArchivioStrumenti basato su localStorage rispettando il contratto salva, trovaPerId e tutti.
Salvare e leggere strumenti da localStorage
Ora costruiamo il primo archivio persistente:
ArchivioStrumentiLocalStorage
Non e un database.
Non e una API.
Ma permette ai dati di restare dopo il refresh della pagina.
Obiettivo
Alla fine devi avere un archivio strumenti che:
- legge strumenti da
localStorage; - salva strumenti in
localStorage; - rispetta il contratto
ArchivioStrumenti; - puo sostituire l’archivio in memoria;
- resta confinato in Infrastructure.
Contratto
L’archivio deve offrire:
salva(strumento)
trovaPerId(id)
tutti()
Se rispetta questo contratto, i casi d’uso possono usarlo.
Chiave localStorage
Scegliamo una chiave:
const CHIAVE_STRUMENTI = "registro-laboratorio:strumenti";
Meglio di:
"strumenti"
Perche una chiave piu specifica riduce collisioni con altri dati nel browser.
Leggere strumenti
function leggiStrumenti() {
const testo = localStorage.getItem(CHIAVE_STRUMENTI);
if (!testo) {
return [];
}
return JSON.parse(testo);
}
Questa e la versione semplice.
Piu avanti gestiremo dati corrotti.
Scrivere strumenti
function scriviStrumenti(strumenti) {
localStorage.setItem(CHIAVE_STRUMENTI, JSON.stringify(strumenti));
}
Anche questa e infrastructure.
Non deve stare in Application.
Implementazione archivio
File:
src/infrastructure/archivioStrumentiLocalStorage.js
Codice:
const CHIAVE_STRUMENTI = "registro-laboratorio:strumenti";
function leggiStrumenti() {
const testo = localStorage.getItem(CHIAVE_STRUMENTI);
return testo ? JSON.parse(testo) : [];
}
function scriviStrumenti(strumenti) {
localStorage.setItem(CHIAVE_STRUMENTI, JSON.stringify(strumenti));
}
export function creaArchivioStrumentiLocalStorage() {
return {
tutti() {
return leggiStrumenti();
},
trovaPerId(id) {
return leggiStrumenti().find((strumento) => strumento.id === id) ?? null;
},
salva(strumento) {
const strumenti = leggiStrumenti();
const indice = strumenti.findIndex((item) => item.id === strumento.id);
if (indice === -1) {
strumenti.push(strumento);
} else {
strumenti[indice] = strumento;
}
scriviStrumenti(strumenti);
return strumento;
},
};
}
Questa versione e leggibile e sufficiente per iniziare.
Usarlo nel punto di composizione
Prima:
const archivioStrumenti = creaArchivioStrumentiInMemoria();
Dopo:
const archivioStrumenti = creaArchivioStrumentiLocalStorage();
I casi d’uso non devono cambiare.
Questa e la prova che il lavoro del modulo 9 e servito.
Verifica manuale
- registra uno strumento;
- ricarica la pagina;
- controlla che lo strumento sia ancora presente;
- modifica lo stato;
- ricarica di nuovo;
- controlla che lo stato sia aggiornato.
Se i dati restano, l’archivio localStorage sta funzionando.
Limiti della versione semplice
Questa implementazione non gestisce ancora bene:
- JSON corrotto;
- dati vecchi;
- campi mancanti;
- errori di quota del browser;
- mapping tra DTO e dominio.
Non e un problema.
Li affronteremo nelle prossime lezioni.
Esercizio
Implementa creaArchivioStrumentiLocalStorage.
Poi compila:
# Verifica ArchivioStrumentiLocalStorage
Metodo tutti:
Metodo trovaPerId:
Metodo salva:
Chiave usata:
Cosa succede dopo refresh:
Cosa ancora non gestisco:
Cosa produrre
Alla fine della lezione devi avere:
- file
archivioStrumentiLocalStorage.js; - chiave localStorage specifica;
- metodi
tutti,trovaPerId,salva; - punto di composizione aggiornabile;
- verifica manuale dopo refresh.
Spiegazione guidata per studiare
Questa lezione va studiata su due piani. Il primo è il comportamento visibile del Registro del laboratorio: che cosa vede o fa l’utente quando registra uno strumento, cerca un dispositivo, apre un prestito o segnala un guasto. Il secondo è il confine architetturale: dove deve stare il codice che rende possibile quel comportamento.
Per salvare e leggere strumenti da localStorage, il punto centrale è questo: L’infrastruttura è il bordo tecnico: salva, legge, chiama API, usa localStorage o file JSON. È importante, ma deve restare sostituibile.
Il rischio tipico è far entrare il formato salvato dentro il dominio. Un oggetto comodo per localStorage non è automaticamente il modello con cui ragiona il progetto. Per evitarlo, non partire dal file che hai già aperto nell’editor. Parti dalla domanda: “quale responsabilità sto modificando?”. Se la risposta riguarda una regola del laboratorio, guarda il dominio. Se riguarda una sequenza di operazioni, guarda i casi d’uso. Se riguarda salvataggio, file, localStorage, API o database, guarda l’infrastruttura. Se riguarda input, pulsanti, form e messaggi, guarda la Presentation.
Il tempo è sufficiente per alternare spiegazione, modifica guidata e revisione. Alla fine della lezione lo studente non deve ricordare una definizione a memoria: deve saper indicare un punto del progetto, spiegare perché quel codice sta lì e mostrare una verifica del comportamento.
Passo per passo nel progetto
- Rileggi il titolo della lezione e riscrivilo come domanda pratica. Per esempio: “dove deve stare questa regola?”, “chi deve salvare questo dato?”, “come verifico questo errore?”.
- Apri solo i file necessari. Se devi toccare più di tre file, fermati e scrivi prima una mini-mappa.
- Distingui modello di dominio e formato salvato.
- Crea una funzione di mapping leggibile.
- Gestisci dati mancanti o non validi.
- Verifica che i casi d’uso non cambino quando cambi archivio.
- Aggiorna una nota breve nel README o negli appunti se hai cambiato un confine del progetto.
Esempio da leggere lentamente
Questo esempio serve a ragionare, non a incollare codice senza capire:
function strumentoToDTO(strumento) {
return {
id: strumento.id,
name: strumento.nome,
category: strumento.categoria,
status: strumento.stato
};
}
Leggilo chiedendoti che cosa cambierebbe se domani sostituissimo la pagina web con una CLI, oppure localStorage con un’API. Se l’esempio continua ad avere senso senza riscrivere tutto, il confine è probabilmente buono. Se invece un dettaglio tecnico si propaga in molti file, il progetto sta tornando fragile.
Prova di comprensione
Prima di chiudere la lezione, rispondi per iscritto a queste domande:
- Qual è la responsabilità principale trattata in questa lezione?
- In quale livello del progetto dovrebbe stare?
- Quale errore faresti se cercassi la soluzione più veloce?
- Quale piccolo test, controllo manuale o esempio dimostra che hai capito?
- Che cosa deve restare facile da cambiare dopo questa lezione?
Una risposta accettabile non deve essere lunga. Deve però usare parole concrete del Registro: strumento, prestito, stato, archivio, caso d’uso, messaggio, test.
Controllo finale
La lezione e completata quando puoi rispondere si:
- gli strumenti vengono salvati in localStorage;
- gli strumenti vengono riletti dopo refresh;
- il caso d’uso non e stato modificato;
- localStorage resta in Infrastructure;
- so indicare i limiti della versione semplice.
Nella prossima lezione facciamo lo stesso con i prestiti.