modulo 09 di 24 / Ore 21-40

Moduli 9-16 / Checkpoint 40 ore

Esercizio: sostituire archivio senza toccare RegistraPrestito

Verificare il modulo sostituendo l'implementazione dell'archivio e controllando che il caso d'uso RegistraPrestito resti invariato.

40 minArchitettura del software

Esercizio: sostituire archivio senza toccare RegistraPrestito

Questa lezione chiude il modulo.

La prova e molto concreta:

Riesco a sostituire l'archivio senza modificare RegistraPrestito?

Se la risposta e si, hai ottenuto il risultato del modulo.

Se la risposta e no, hai trovato accoppiamento da ridurre.

Obiettivo

Sostituire l’archivio usato da RegistraPrestito mantenendo invariato il caso d’uso.

Puoi farlo in modo semplice:

  • archivio in memoria normale;
  • archivio in memoria tracciato;
  • fake archivio per test;
  • prima bozza di archivio localStorage, se la classe e pronta.

Non serve completare localStorage in questa lezione. Arrivera nel modulo successivo.

Punto di partenza

RegistraPrestito dovrebbe essere costruito cosi:

const registraPrestito = creaRegistraPrestito({
  archivioStrumenti,
  archivioPrestiti,
});

Il caso d’uso usa:

archivioStrumenti.trovaPerId(...)
archivioStrumenti.salva(...)
archivioPrestiti.tutti(...)
archivioPrestiti.salva(...)

Non deve importare direttamente:

archivioStrumentiInMemoria
localStorage
JSON

Archivio alternativo semplice

Creiamo un archivio tracciato.

Serve solo per verificare che il caso d’uso chiami i metodi attesi.

export function creaArchivioStrumentiTracciato(datiIniziali = []) {
  const strumenti = [...datiIniziali];
  const chiamate = [];

  return {
    chiamate,

    trovaPerId(id) {
      chiamate.push(`trovaPerId:${id}`);
      return strumenti.find((strumento) => strumento.id === id) ?? null;
    },

    salva(strumento) {
      chiamate.push(`salva:${strumento.id}`);
      const indice = strumenti.findIndex((item) => item.id === strumento.id);

      if (indice === -1) {
        strumenti.push(strumento);
      } else {
        strumenti[indice] = strumento;
      }

      return strumento;
    },

    tutti() {
      chiamate.push("tutti");
      return [...strumenti];
    },
  };
}

Questo archivio rispetta il contratto.

In piu registra le chiamate.

Usarlo senza toccare RegistraPrestito

Nel test o nello script:

const archivioStrumenti = creaArchivioStrumentiTracciato([
  {
    id: "s-001",
    nome: "Arduino Uno",
    categoria: "microcontrollori",
    stato: "disponibile",
  },
]);

const archivioPrestiti = creaArchivioPrestitiInMemoria();

const registraPrestito = creaRegistraPrestito({
  archivioStrumenti,
  archivioPrestiti,
});

registraPrestito({
  prestitoId: "p-001",
  strumentoId: "s-001",
  assegnatario: "Luca 3A",
  apertoIl: "2026-05-09",
});

console.log(archivioStrumenti.chiamate);

Risultato atteso:

trovaPerId:s-001
salva:s-001

L’ordine puo dipendere dal tuo codice, ma deve essere chiaro che il caso d’uso usa il contratto.

Regola dell’esercizio

Durante l’esercizio e vietato modificare:

src/application/registraPrestito.js

Puoi modificare:

  • punto di composizione;
  • script di test;
  • archivio alternativo;
  • dati iniziali.

Se devi modificare RegistraPrestito, significa che e ancora troppo legato all’archivio concreto.

Variante con localStorage preparatoria

Se vuoi anticipare il modulo successivo, puoi creare una bozza:

export function creaArchivioStrumentiLocalStorage() {
  return {
    tutti() {
      return JSON.parse(localStorage.getItem("strumenti") ?? "[]");
    },

    trovaPerId(id) {
      return this.tutti().find((strumento) => strumento.id === id) ?? null;
    },

    salva(strumento) {
      const strumenti = this.tutti();
      const indice = strumenti.findIndex((item) => item.id === strumento.id);

      if (indice === -1) {
        strumenti.push(strumento);
      } else {
        strumenti[indice] = strumento;
      }

      localStorage.setItem("strumenti", JSON.stringify(strumenti));
      return strumento;
    },
  };
}

Non e ancora la versione definitiva.

Serve solo a vedere che il contratto permette la sostituzione.

Nel modulo 10 lavoreremo meglio su DTO, mapping e dati corrotti.

Scheda di verifica

Compila:

# Sostituzione archivio

Caso d'uso:
RegistraPrestito

Archivio iniziale:

Archivio sostitutivo:

File modificati:
- ...

File non modificato:
- src/application/registraPrestito.js

Metodi del contratto usati:
- ...

Risultato:

Problemi trovati:

Errori comuni

Errore:

Ho dovuto cambiare RegistraPrestito per usare il nuovo archivio.

Possibile causa:

Il caso d'uso conosce dettagli dell'archivio concreto.

Errore:

Il nuovo archivio non ha tutti().

Possibile causa:

Non rispetta il contratto richiesto.

Errore:

L'archivio restituisce undefined quando non trova.

Possibile causa:

Il contratto non e stato rispettato: trovaPerId deve restituire null.

Cosa produrre

Alla fine della lezione devi avere:

  • archivio alternativo;
  • punto di composizione aggiornato o script di prova;
  • RegistraPrestito non modificato;
  • scheda di verifica compilata;
  • elenco dei metodi del contratto usati;
  • eventuali problemi emersi.

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 esercizio: sostituire archivio senza toccare RegistraPrestito, 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 del modulo

Il Modulo 9 e completato quando puoi rispondere si:

  • so distinguere dipendenza concreta e contratto;
  • ho definito operazioni minime per ArchivioStrumenti;
  • un archivio in memoria rispetta il contratto;
  • i casi d’uso ricevono dipendenze dall’esterno;
  • so spiegare inversione del controllo senza framework;
  • so dove si compone l’applicazione;
  • ho sostituito un archivio senza toccare RegistraPrestito.

Nel prossimo modulo useremo questa base per affrontare Infrastructure in modo piu concreto: localStorage, JSON, DTO, mapping e adapter.