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.

30 min Architettura del software

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

  1. registra uno strumento;
  2. ricarica la pagina;
  3. controlla che lo strumento sia ancora presente;
  4. modifica lo stato;
  5. ricarica di nuovo;
  6. 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

  1. 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?”.
  2. Apri solo i file necessari. Se devi toccare più di tre file, fermati e scrivi prima una mini-mappa.
  3. Distingui modello di dominio e formato salvato.
  4. Crea una funzione di mapping leggibile.
  5. Gestisci dati mancanti o non validi.
  6. Verifica che i casi d’uso non cambino quando cambi archivio.
  7. 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.