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.
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
- 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:
- 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.