modulo 07 di 24 / Ore 0-20
Moduli 1-8 / Checkpoint 20 ore
CercaStrumenti: filtri per nome, categoria e stato
Costruire il caso d'uso CercaStrumenti distinguendo filtri, normalizzazione dell'input e lettura dall'archivio.
CercaStrumenti: filtri per nome, categoria e stato
Il secondo caso d’uso e:
CercaStrumenti
Scopo:
Trovare strumenti per nome, categoria o stato.
Questo caso d’uso e utile per chiarire una cosa: non tutte le operazioni modificano dati.
Cercare strumenti legge, filtra e restituisce risultati.
Obiettivo
Alla fine devi avere un caso d’uso che:
- legge gli strumenti dall’archivio;
- applica filtri opzionali;
- non modifica i dati;
- non dipende dalla UI;
- restituisce una lista.
Il comando di ricerca
Il comando puo essere:
const comando = {
testo: "arduino",
categoria: "microcontrollori",
stato: "disponibile",
};
Tutti i campi possono essere opzionali.
Esempi:
cercaStrumenti({ testo: "kit" });
cercaStrumenti({ stato: "guasto" });
cercaStrumenti({ categoria: "audio", stato: "disponibile" });
cercaStrumenti({});
Se il comando e vuoto, possiamo restituire tutti gli strumenti.
Archivio
L’archivio deve offrire una operazione per leggere gli strumenti.
Esempio:
const archivioStrumenti = {
tutti() {
return strumenti;
},
};
Piu avanti potremmo decidere se il filtro deve stare nell’archivio o nel caso d’uso.
Per ora, con dati piccoli e laboratorio didattico, possiamo filtrare nel caso d’uso.
Normalizzare l’input
Per cercare in modo piu robusto:
function normalizzaTesto(valore) {
return valore.trim().toLowerCase();
}
Questo permette di trattare:
Arduino
arduino
ARDUINO
come ricerche equivalenti.
Non e una regola profonda di dominio. E una scelta applicativa utile per la ricerca.
Implementazione
File:
src/application/cercaStrumenti.js
Codice:
function normalizzaTesto(valore) {
return String(valore ?? "").trim().toLowerCase();
}
export function creaCercaStrumenti({ archivioStrumenti }) {
return function cercaStrumenti(filtri = {}) {
const strumenti = archivioStrumenti.tutti();
const testo = normalizzaTesto(filtri.testo);
const categoria = normalizzaTesto(filtri.categoria);
const stato = normalizzaTesto(filtri.stato);
return strumenti.filter((strumento) => {
const nomeCorrisponde =
!testo || normalizzaTesto(strumento.nome).includes(testo);
const categoriaCorrisponde =
!categoria || normalizzaTesto(strumento.categoria) === categoria;
const statoCorrisponde =
!stato || normalizzaTesto(strumento.stato) === stato;
return nomeCorrisponde && categoriaCorrisponde && statoCorrisponde;
});
};
}
Il caso d’uso riceve filtri e restituisce strumenti.
Non mostra “nessun risultato”. Quello e compito della UI.
La UI decide come mostrare risultati vuoti
Il caso d’uso puo restituire:
[]
La UI puo trasformarlo in:
Nessuno strumento trovato.
Non serve che CercaStrumenti conosca quel messaggio.
Attenzione: cercare non deve modificare
Questa e una regola pratica:
CercaStrumenti non modifica strumenti.
Quindi non deve:
- cambiare stato;
- salvare dati;
- ordinare modificando l’array originale se non previsto;
- correggere automaticamente categorie;
- creare strumenti mancanti.
Legge e restituisce.
Scenari
Scrivi:
## Scenario 1
Dato un elenco di strumenti,
quando cerco "arduino",
allora ottengo gli strumenti con nome che contiene "arduino".
## Scenario 2
Dato un elenco di strumenti,
quando filtro per stato disponibile,
allora ottengo solo strumenti disponibili.
## Scenario 3
Dato un elenco di strumenti,
quando uso filtri vuoti,
allora ottengo tutti gli strumenti.
## Scenario 4
Dato un elenco di strumenti,
quando non ci sono corrispondenze,
allora ottengo una lista vuota.
Esercizio
Prepara questi dati:
const strumenti = [
{ id: "s-001", nome: "Arduino Uno", categoria: "microcontrollori", stato: "disponibile" },
{ id: "s-002", nome: "Kit sensori", categoria: "robotica", stato: "in_prestito" },
{ id: "s-003", nome: "Multimetro", categoria: "misura", stato: "guasto" },
];
Verifica:
- ricerca per nome
arduino; - ricerca per categoria
robotica; - ricerca per stato
guasto; - ricerca con testo non presente;
- ricerca con filtri vuoti.
Cosa produrre
Alla fine della lezione devi avere:
- file
src/application/cercaStrumenti.js; - caso d’uso
CercaStrumenti; - filtri per nome, categoria e stato;
- almeno quattro scenari;
- nessun messaggio UI dentro il caso d’uso;
- garanzia che la ricerca non modifica i dati.
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 cercaStrumenti: filtri per nome, categoria e stato, il punto centrale è questo: Un caso d’uso coordina un’operazione completa: riceve un comando, legge ciò che serve, applica regole, salva il risultato e restituisce un esito.
Il rischio tipico è far diventare il caso d’uso una seconda UI o un secondo database. Deve coordinare, non mostrare HTML e non conoscere dettagli tecnici di salvataggio. 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.
- Definisci input e output del caso d’uso.
- Leggi i dati attraverso un archivio o una dipendenza esplicita.
- Chiama le regole del dominio.
- Salva il risultato senza sapere come funziona la persistenza concreta.
- 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 registraPrestito(comando, archivioStrumenti, archivioPrestiti) {
const strumento = archivioStrumenti.trovaPerId(comando.strumentoId);
verificaStrumentoPrestabile(strumento);
const prestito = apriPrestito(strumento.id, comando.nomePersona);
archivioPrestiti.salva(prestito);
archivioStrumenti.salva({ ...strumento, stato: "in_prestito" });
return prestito;
}
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:
- posso cercare per nome;
- posso filtrare per categoria;
- posso filtrare per stato;
- la ricerca restituisce una lista vuota se non trova nulla;
- il caso d’uso non aggiorna lo stato degli strumenti;
- la UI decide come mostrare i risultati.
Nella prossima lezione costruiamo il caso d’uso piu importante: RegistraPrestito.