modulo 07 di 24 / Ore 0-20
Moduli 1-8 / Checkpoint 20 ore
RegistraStrumento: input, validazione minima e salvataggio
Costruire il caso d'uso RegistraStrumento coordinando input, modello di dominio e archivio, senza dipendere dalla UI.
RegistraStrumento: input, validazione minima e salvataggio
Il primo caso d’uso che costruiamo e:
RegistraStrumento
Scopo:
Aggiungere al registro uno strumento valido.
Sembra semplice, ed e proprio per questo e un buon punto di partenza.
Obiettivo
Alla fine devi avere un caso d’uso che:
- riceve i dati dello strumento;
- crea uno
Strumentousando il dominio; - salva lo strumento in un archivio;
- restituisce lo strumento registrato;
- non legge direttamente dalla UI;
- non usa direttamente
localStorage.
Il comando
Il caso d’uso riceve un comando.
Esempio:
const comando = {
id: "s-001",
nome: "Arduino Uno",
categoria: "microcontrollori",
stato: "disponibile",
};
La UI puo costruire questo oggetto leggendo un form, ma il caso d’uso non deve sapere da dove arriva.
Il comando potrebbe arrivare anche da:
- test;
- CLI;
- file;
- API futura.
Il dominio crea lo strumento
Nel dominio abbiamo una funzione simile:
export function creaStrumento({ id, nome, categoria, stato }) {
if (!nome || nome.trim() === "") {
throw new Error("NOME_STRUMENTO_OBBLIGATORIO");
}
return {
id: id.trim(),
nome: nome.trim(),
categoria: categoria.trim(),
stato,
};
}
Il caso d’uso non deve duplicare questa validazione.
Deve chiamarla.
Archivio in memoria minimo
Per ora possiamo usare un archivio semplice.
File:
src/infrastructure/archivioStrumentiInMemoria.js
Esempio:
export function creaArchivioStrumentiInMemoria() {
const strumenti = [];
return {
salva(strumento) {
strumenti.push(strumento);
return strumento;
},
tutti() {
return [...strumenti];
},
};
}
Questo archivio e ancora semplice. Piu avanti lo sostituiremo con localStorage.
La cosa importante e che il caso d’uso non deve conoscere come l’archivio salva i dati.
Scrivere il caso d’uso
File:
src/application/registraStrumento.js
Codice:
import { creaStrumento } from "../domain/strumento.js";
export function creaRegistraStrumento({ archivioStrumenti }) {
return function registraStrumento(comando) {
const strumento = creaStrumento({
id: comando.id,
nome: comando.nome,
categoria: comando.categoria,
stato: comando.stato,
});
archivioStrumenti.salva(strumento);
return strumento;
};
}
Questa forma usa una funzione che riceve le dipendenze e restituisce il caso d’uso.
Non serve chiamarla subito “dependency injection”. Basta capire il vantaggio:
posso passare archivi diversi senza cambiare il caso d'uso
Uso dal codice di avvio
Nel punto di avvio dell’applicazione:
const archivioStrumenti = creaArchivioStrumentiInMemoria();
const registraStrumento = creaRegistraStrumento({
archivioStrumenti,
});
registraStrumento({
id: "s-001",
nome: "Arduino Uno",
categoria: "microcontrollori",
stato: "disponibile",
});
Questo codice puo stare in main.js o in un file di composizione.
Uso dalla UI
La UI puo fare:
form.addEventListener("submit", (event) => {
event.preventDefault();
const comando = {
id: inputId.value,
nome: inputNome.value,
categoria: inputCategoria.value,
stato: selectStato.value,
};
try {
registraStrumento(comando);
mostraMessaggio("Strumento registrato.");
} catch (errore) {
mostraMessaggio(messaggioPerErrore(errore));
}
});
Qui la UI legge input e mostra messaggi.
Il caso d’uso registra lo strumento.
Il dominio valida lo strumento.
L’archivio salva.
Validazione minima
Nel caso d’uso possiamo fare solo validazioni applicative se servono.
Esempio:
Il comando deve esistere.
Ma non dobbiamo duplicare:
nome obbligatorio
stato valido
categoria obbligatoria
Se sono regole del modello Strumento, restano nel dominio.
Scenario
Scrivi:
## Caso d'uso
RegistraStrumento
## Scenario valido
Dato un comando con id, nome, categoria e stato validi,
quando registro lo strumento,
allora lo strumento viene salvato nell'archivio e restituito.
## Scenario non valido
Dato un comando senza nome,
quando registro lo strumento,
allora ottengo errore NOME_STRUMENTO_OBBLIGATORIO e nulla viene salvato.
Esercizio
Implementa o descrivi RegistraStrumento.
Poi verifica manualmente:
- registro uno strumento valido;
- controllo che sia nell’archivio;
- provo a registrare uno strumento senza nome;
- controllo che non venga salvato;
- verifico che la UI mostri un messaggio comprensibile.
Cosa produrre
Alla fine della lezione devi avere:
- file
src/application/registraStrumento.js; - caso d’uso
RegistraStrumento; - archivio in memoria minimo o equivalente;
- almeno due scenari;
- nessun riferimento a
document.querySelectornel caso d’uso; - nessun riferimento diretto a
localStoragenel caso d’uso.
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 registraStrumento: input, validazione minima e salvataggio, il punto centrale è questo: Gestire errori significa distinguere origine, significato e messaggio. Un errore di dominio non è uguale a un campo mancante o a un salvataggio fallito.
Il rischio tipico è mostrare all’utente il messaggio tecnico grezzo oppure nascondere tutti gli errori dietro una frase generica. L’utente deve sapere cosa fare; chi mantiene il sistema deve poter capire cosa è successo. 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.
- Classifica l’errore: input, dominio, applicazione o infrastruttura.
- Scrivi un messaggio utente breve e utile.
- Conserva il dettaglio tecnico solo dove serve.
- Testa almeno uno scenario di errore.
- 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:
const messaggi = {
STRUMENTO_NON_TROVATO: "Strumento non trovato.",
STRUMENTO_GUASTO_NON_PRESTABILE: "Questo strumento è guasto e non può essere prestato.",
ARCHIVIO_NON_DISPONIBILE: "Non riesco a salvare i dati. Riprova tra poco."
};
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:
- il caso d’uso riceve un comando;
- il dominio crea lo strumento;
- l’archivio salva lo strumento;
- la UI non contiene la logica di registrazione;
- posso chiamare
RegistraStrumentoda un test.
Nella prossima lezione costruiamo CercaStrumenti.