modulo 09 di 24 / Ore 21-40

Moduli 9-16 / Checkpoint 40 ore

Definire ArchivioStrumenti con operazioni minime

Stabilire il contratto minimo di ArchivioStrumenti: salvare, cercare per id, leggere tutti gli strumenti e sostituire implementazioni.

30 minArchitettura del software

Definire ArchivioStrumenti con operazioni minime

Ora diamo una forma chiara al contratto:

ArchivioStrumenti

Non partiamo chiedendoci quale database usare.

Partiamo chiedendoci:

Quali operazioni servono davvero ai casi d'uso?

Obiettivo

Alla fine devi avere un contratto minimo per ArchivioStrumenti, scritto in modo comprensibile e usato dai casi d’uso.

Il contratto deve essere piccolo.

Se mettiamo troppe operazioni, stiamo progettando un archivio generico invece di risolvere il problema del registro.

Operazioni necessarie

Per i casi d’uso gia costruiti servono almeno:

salva(strumento)
trovaPerId(id)
tutti()

Perche?

RegistraStrumento ha bisogno di:

salva(strumento)

RegistraPrestito ha bisogno di:

trovaPerId(id)
salva(strumentoAggiornato)

CercaStrumenti ha bisogno di:

tutti()

ChiudiPrestito ha bisogno di:

trovaPerId(id)
salva(strumentoAggiornato)

Quindi il contratto nasce dai casi d’uso, non dalla fantasia.

Contratto in JavaScript

In JavaScript possiamo documentarlo cosi:

/**
 * ArchivioStrumenti
 *
 * Deve offrire:
 * - salva(strumento): salva o aggiorna uno strumento
 * - trovaPerId(id): restituisce uno strumento oppure null
 * - tutti(): restituisce la lista degli strumenti
 */

Possiamo metterlo in:

src/application/contratti.js

oppure nel README tecnico.

Non serve complicare se il progetto e piccolo.

Contratto in TypeScript leggero

Se usi TypeScript:

export type ArchivioStrumenti = {
  salva(strumento: Strumento): Strumento;
  trovaPerId(id: string): Strumento | null;
  tutti(): Strumento[];
};

Questo rende il contratto controllabile dal linguaggio.

Nel corso possiamo restare su JavaScript modulare e documentare bene.

Comportamento atteso

Il contratto non e solo nomi di metodi.

Serve anche spiegare il comportamento.

## salva(strumento)

Se lo strumento non esiste, lo aggiunge.
Se esiste gia uno strumento con lo stesso id, lo aggiorna.
Restituisce lo strumento salvato.

## trovaPerId(id)

Restituisce lo strumento con quell'id.
Se non esiste, restituisce null.

## tutti()

Restituisce tutti gli strumenti.
Non deve permettere modifiche accidentali all'archivio interno.

Queste frasi evitano interpretazioni diverse.

Cosa non mettere nel contratto

Evita di aggiungere subito:

connetti()
disconnetti()
salvaTutti()
cancellaTutto()
backup()
sincronizza()
ordinaPerNome()
filtraPerCategoria()

Forse serviranno.

Forse no.

Per ora il contratto deve supportare i casi d’uso reali.

Nomi coerenti

Scegli nomi semplici.

Esempio:

salva
trovaPerId
tutti

Non mescolare:

save
findById
getAll

Se il progetto usa italiano, resta in italiano.

Se usa inglese, resta in inglese.

Il punto e la coerenza.

ArchivioStrumenti e ArchivioPrestiti

Possiamo definire anche:

ArchivioPrestiti

Operazioni minime:

salva(prestito)
trovaPerId(id)
tutti()

Per ora i due contratti sono simili.

Non serve creare una astrazione generica subito.

La duplicazione e accettabile se rende il progetto piu leggibile.

Scheda contratto

Compila:

# Contratto ArchivioStrumenti

## Scopo

## Operazioni

### salva(strumento)

Input:
Output:
Comportamento:

### trovaPerId(id)

Input:
Output:
Comportamento:

### tutti()

Input:
Output:
Comportamento:

## Casi d'uso che lo usano

- ...

Esercizio

Guarda i casi d’uso:

  • RegistraStrumento;
  • CercaStrumenti;
  • RegistraPrestito;
  • ChiudiPrestito.

Per ogni caso d’uso scrivi quali metodi usa dell’archivio.

Se trovi un caso d’uso che accede direttamente a un array, annota quale metodo manca nel contratto.

Cosa produrre

Alla fine della lezione devi avere:

  • contratto ArchivioStrumenti;
  • comportamento atteso dei metodi;
  • eventuale contratto ArchivioPrestiti;
  • lista dei casi d’uso che usano ogni metodo;
  • scelta coerente dei nomi.

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 definire ArchivioStrumenti con operazioni minime, 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:

  • so quali metodi minimi servono;
  • il contratto nasce dai casi d’uso;
  • ho evitato operazioni premature;
  • so cosa deve restituire trovaPerId;
  • so cosa deve fare salva;
  • posso implementare archivi diversi con la stessa forma.

Nella prossima lezione useremo un archivio in memoria attraverso questo contratto.