modulo 06 di 24 / Ore 0-20

Moduli 1-8 / Checkpoint 20 ore

StatoStrumento: disponibile, in prestito, guasto, in manutenzione

Definire gli stati possibili di uno strumento e usarli come parte del dominio, evitando stringhe sparse e stati ambigui.

25 min Architettura del software

StatoStrumento: disponibile, in prestito, guasto, in manutenzione

Lo stato di uno strumento dice che cosa può succedere a quello strumento.

Non è solo un testo da mostrare in una tabella. Non è solo un badge colorato. È una parte del dominio, perché influenza le regole principali del Registro.

Se uno strumento è disponibile, può essere prestato. Se è guasto, non può essere prestato. Se è in_manutenzione, non deve essere usato finché qualcuno non lo rimette disponibile. Se è in_prestito, non può essere prestato a un’altra persona nello stesso momento.

Quindi lo stato non descrive soltanto come appare lo strumento. Descrive che cosa il sistema deve permettere o rifiutare.

Obiettivo della lezione

Alla fine devi avere:

  • una lista chiara degli stati ammessi;
  • una costante StatoStrumento;
  • una funzione per verificare se uno stato è valido;
  • alcune funzioni di lettura, come isDisponibile;
  • una tabella con significato, regole e transizioni principali;
  • esempi di stati corretti e stati da rifiutare.

Il risultato deve rendere il codice meno fragile: niente stringhe ripetute a mano, niente sinonimi casuali, niente stati inventati in un file e dimenticati negli altri.

Perché evitare stringhe sparse

Questo codice sembra innocuo:

if (strumento.stato === "disponibile") {
  // registra il prestito
}

Il problema arriva quando in altri punti del progetto qualcuno scrive:

Disponibile
disponibili
available
libero
in prestito
in_prestito
prestato
rotto
guasto
da riparare

Il programma può iniziare a sbagliare per una differenza di maiuscole, spazi, lingua o sinonimo. Il caso peggiore è silenzioso: il codice non esplode, ma una regola non viene applicata.

Esempio:

if (strumento.stato === "guasto") {
  throw new Error("STRUMENTO_GUASTO_NON_PRESTABILE");
}

Se uno strumento ha stato "rotto", questa regola non lo blocca. Per una persona “rotto” e “guasto” sono quasi sinonimi. Per il programma sono due stringhe diverse.

La soluzione non è complicata: centralizziamo gli stati ammessi.

Definire StatoStrumento

File:

src/domain/statoStrumento.js

Codice:

export const StatoStrumento = {
  DISPONIBILE: "disponibile",
  IN_PRESTITO: "in_prestito",
  GUASTO: "guasto",
  IN_MANUTENZIONE: "in_manutenzione",
};

Ora il resto del dominio può usare:

strumento.stato === StatoStrumento.DISPONIBILE

Non è una magia. È un modo semplice per evitare stringhe ripetute a mano.

Se in futuro decidiamo di cambiare il valore interno da "in_prestito" a "prestato", abbiamo un punto chiaro da controllare. Ancora meglio: se usiamo sempre la costante, molte parti del codice non dovranno cambiare.

Significato degli stati

Uno stato deve avere un significato pratico. Se non cambia nulla nel comportamento del sistema, forse non serve come stato.

disponibile

Lo strumento è presente, utilizzabile e può essere prestato.

Regole:

  • può essere prestato;
  • può essere segnato come guasto;
  • può andare in manutenzione;
  • può essere mostrato tra gli strumenti utilizzabili.

Esempio:

{
  id: "str-001",
  nome: "Arduino Uno",
  categoria: "microcontrollori",
  stato: StatoStrumento.DISPONIBILE,
}

in_prestito

Lo strumento è stato assegnato a una persona o a un gruppo e non è disponibile per altri.

Regole:

  • non può essere prestato di nuovo;
  • dovrebbe avere un prestito aperto collegato;
  • può tornare disponibile alla chiusura del prestito;
  • può diventare guasto o in manutenzione se viene restituito con problemi.

Qui compare una domanda importante:

Come facciamo a sapere quale prestito è collegato allo strumento?

Non la risolviamo dentro StatoStrumento. La affronteremo modellando Prestito e poi nei casi d’uso.

guasto

Lo strumento ha un problema noto e non deve essere usato.

Regole:

  • non può essere prestato;
  • deve essere visibile al tecnico;
  • può passare in manutenzione;
  • può tornare disponibile solo dopo una decisione esplicita.

Esempio:

Il proiettore si accende, ma non mostra immagine.

In questo caso lo stato guasto è più preciso di una nota generica. Il sistema deve impedire il prestito.

in_manutenzione

Lo strumento è in controllo, riparazione o verifica.

Regole:

  • non può essere prestato;
  • non va confuso con guasto;
  • può tornare disponibile;
  • può tornare guasto se la riparazione non risolve il problema.

Differenza pratica:

  • guasto: sappiamo che c’è un problema;
  • in_manutenzione: qualcuno sta controllando o riparando lo strumento.

Questa distinzione aiuta il tecnico. Uno strumento guasto è da prendere in carico; uno strumento in manutenzione è già dentro un processo di controllo.

Stato valido

Aggiungiamo una funzione per verificare che lo stato appartenga alla lista ammessa.

export function isStatoStrumentoValido(stato) {
  return Object.values(StatoStrumento).includes(stato);
}

Poi la usiamo in creaStrumento:

import { isStatoStrumentoValido } from "./statoStrumento.js";

export function creaStrumento({ id, nome, categoria, stato }) {
  if (!isStatoStrumentoValido(stato)) {
    throw new Error("STATO_STRUMENTO_NON_VALIDO");
  }

  return {
    id,
    nome,
    categoria,
    stato,
  };
}

Questa funzione impedisce stati inventati:

rotto
prestato
ok
non disponibile
da vedere
libero

Se servono nuovi stati, li aggiungeremo in modo esplicito. Questo è il punto: uno stato nuovo deve essere una decisione, non un refuso.

Funzioni di lettura

Possiamo aggiungere funzioni piccole per rendere il codice più leggibile.

export function isDisponibile(strumento) {
  return strumento.stato === StatoStrumento.DISPONIBILE;
}

export function isInPrestito(strumento) {
  return strumento.stato === StatoStrumento.IN_PRESTITO;
}

export function isGuasto(strumento) {
  return strumento.stato === StatoStrumento.GUASTO;
}

export function isInManutenzione(strumento) {
  return strumento.stato === StatoStrumento.IN_MANUTENZIONE;
}

Confronta questa versione:

if (
  strumento.stato !== "guasto" &&
  strumento.stato !== "in_manutenzione" &&
  strumento.stato !== "in_prestito"
) {
  // presta
}

Con questa:

if (isDisponibile(strumento)) {
  // presta
}

La seconda versione dice meglio l’intenzione. Non siamo interessati a tutte le condizioni negative; vogliamo sapere se lo strumento è disponibile.

Funzione di dominio: può essere prestato?

Possiamo aggiungere una funzione ancora più vicina alla regola:

export function puoEsserePrestato(strumento) {
  return isDisponibile(strumento);
}

Sembra banale, ma migliora il linguaggio del codice. Un caso d’uso che legge:

if (!puoEsserePrestato(strumento)) {
  throw new Error("STRUMENTO_NON_PRESTABILE");
}

è più chiaro di un caso d’uso pieno di confronti tra stringhe.

Per ora puoEsserePrestato coincide con isDisponibile. In futuro potremmo aggiungere regole diverse senza cambiare tutti i punti in cui registriamo un prestito.

Transizioni di stato

Una transizione è un cambio da uno stato a un altro.

Esempi:

disponibile -> in_prestito
in_prestito -> disponibile
in_prestito -> guasto
guasto -> in_manutenzione
in_manutenzione -> disponibile
in_manutenzione -> guasto

Non tutte le transizioni sono uguali.

Alcune sono normali:

disponibile -> in_prestito
in_prestito -> disponibile

Alcune richiedono una motivazione:

disponibile -> guasto
in_prestito -> guasto

Alcune vanno chiarite:

guasto -> disponibile

È ammessa direttamente? Oppure deve passare sempre da in_manutenzione? La risposta dipende da come il docente vuole organizzare il laboratorio.

Nel corso base non costruiamo subito una macchina a stati complessa. Però annotiamo le transizioni importanti, perché ci aiuteranno nelle lezioni sui casi d’uso.

Tabella pratica degli stati

Compila una tabella nel README o in docs/modello-dominio.md.

# Stati dello strumento

| Stato | Significato | Può essere prestato? | Transizioni principali |
| --- | --- | --- | --- |
| disponibile | Lo strumento è utilizzabile. | sì | in_prestito, guasto, in_manutenzione |
| in_prestito | Lo strumento è assegnato a qualcuno. | no | disponibile, guasto, in_manutenzione |
| guasto | Lo strumento ha un problema noto. | no | in_manutenzione |
| in_manutenzione | Lo strumento è in controllo o riparazione. | no | disponibile, guasto |

Questa tabella aiuta a evitare interpretazioni diverse. Se uno studente pensa che guasto e in_manutenzione siano la stessa cosa, la tabella rende visibile la differenza.

Esercizio guidato

Per ogni situazione scegli lo stato corretto e indica se lo strumento può essere prestato.

1. Il multimetro è nell'armadio e funziona.
2. Il kit Arduino è stato consegnato a uno studente.
3. Il proiettore si accende ma non mostra immagine.
4. La stampante 3D è sul banco del tecnico per controllo.
5. Il notebook torna dal prestito con tastiera rotta.
6. Il microscopio è stato riparato e verificato dal tecnico.

Possibile soluzione:

1. disponibile, può essere prestato.
2. in_prestito, non può essere prestato.
3. guasto, non può essere prestato.
4. in_manutenzione, non può essere prestato.
5. guasto oppure in_manutenzione, da chiarire in base alla procedura.
6. disponibile, può essere prestato.

La riga 5 è volutamente ambigua. Potresti decidere che uno strumento restituito con un problema diventa subito guasto, e poi il tecnico lo mette in_manutenzione quando lo prende in carico. Oppure potresti decidere che va direttamente in_manutenzione. L’importante è scrivere la regola.

Mini-test manuali

Prima di andare avanti, prova mentalmente o in console questi casi.

isStatoStrumentoValido("disponibile"); // true
isStatoStrumentoValido("rotto"); // false
isStatoStrumentoValido("in_prestito"); // false
isStatoStrumentoValido("in_prestito"); // true

Poi verifica la regola di prestabilità:

puoEsserePrestato({ stato: StatoStrumento.DISPONIBILE }); // true
puoEsserePrestato({ stato: StatoStrumento.GUASTO }); // false
puoEsserePrestato({ stato: StatoStrumento.IN_MANUTENZIONE }); // false
puoEsserePrestato({ stato: StatoStrumento.IN_PRESTITO }); // false

Questi esempi sono piccoli, ma preparano i test automatici. Quando arriveremo ai test, sapremo già quali comportamenti controllare.

Cosa produrre

Alla fine della lezione devi avere:

  • file src/domain/statoStrumento.js;
  • costante StatoStrumento;
  • funzione isStatoStrumentoValido;
  • funzioni isDisponibile, isInPrestito, isGuasto, isInManutenzione;
  • funzione puoEsserePrestato;
  • tabella degli stati nel README o in docs/modello-dominio.md;
  • almeno due transizioni da chiarire con il docente o con il gruppo.

Controllo finale

La lezione è completata quando puoi rispondere sì a queste domande:

  • ho definito gli stati ammessi;
  • non uso stringhe diverse per lo stesso stato;
  • so spiegare la differenza tra guasto e in_manutenzione;
  • so quali stati impediscono il prestito;
  • ho annotato le transizioni principali;
  • il controllo dello stato vive nel dominio, non nella UI;
  • posso verificare gli stati senza aprire il browser.

Nella prossima lezione modelliamo Prestito. Lo stato dello strumento ci servirà subito, perché un prestito non può essere aperto senza cambiare ciò che sappiamo dello strumento.