modulo 08 di 24 / Ore 0-20

Moduli 1-8 / Checkpoint 20 ore

Disegnare i quattro livelli del progetto

Rendere visibile la prima architettura del Registro del laboratorio distinguendo Presentation, Application, Domain e Infrastructure.

25 minArchitettura del software

Disegnare i quattro livelli del progetto

Prima di spostare file e funzioni, disegniamo il progetto.

Non serve un diagramma elegante.

Serve una mappa utile:

Presentation
Application
Domain
Infrastructure

Questa mappa deve aiutare lo studente a capire dove inizia e dove finisce ogni responsabilita.

Obiettivo

Alla fine devi avere:

  • uno schema dei quattro livelli;
  • una lista delle responsabilita di ogni livello;
  • esempi concreti presi dal Registro del laboratorio;
  • una prima mappa del flusso di una operazione.

I quattro livelli

Nel nostro corso usiamo questa divisione:

Presentation / UI
  mostra dati, riceve input, chiama i casi d'uso

Application
  coordina le operazioni del sistema

Domain
  contiene regole, concetti e invarianti

Infrastructure
  salva dati, legge file, usa localStorage, database, API o strumenti esterni

Non e una formula da copiare senza pensare.

E una mappa di lavoro per evitare che tutto finisca nello stesso file.

Presentation

Presentation e il bordo visibile del sistema.

Nel nostro progetto puo essere:

  • una pagina HTML;
  • una piccola UI browser;
  • una CLI semplice;
  • un pannello di prova.

Responsabilita:

  • leggere input dall’utente;
  • mostrare liste e dettagli;
  • mostrare messaggi;
  • trasformare click e submit in comandi per i casi d’uso;
  • non contenere regole importanti del dominio.

Esempio:

const comando = {
  strumentoId: inputStrumentoId.value,
  assegnatario: inputAssegnatario.value,
  apertoIl: inputData.value,
};

registraPrestito(comando);

La UI prepara il comando.

Non decide da sola se lo strumento puo essere prestato.

Application

Application contiene i casi d’uso.

Responsabilita:

  • coordinare operazioni;
  • leggere dati dagli archivi;
  • chiamare funzioni del dominio;
  • salvare risultati tramite infrastruttura;
  • restituire risultati o errori.

Esempi:

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

Application non deve sapere quale bottone ha avviato l’operazione.

Domain

Domain contiene il linguaggio del problema.

Responsabilita:

  • rappresentare Strumento;
  • rappresentare Prestito;
  • definire StatoStrumento;
  • proteggere invarianti;
  • esprimere regole come “solo uno strumento disponibile puo essere prestato”.

Esempio:

export function verificaStrumentoPrestabile(strumento) {
  if (strumento.stato !== StatoStrumento.DISPONIBILE) {
    throw new Error("STRUMENTO_NON_PRESTABILE");
  }
}

Questa funzione non sa nulla della pagina web.

Infrastructure

Infrastructure contiene i dettagli tecnici.

Responsabilita:

  • salvare e leggere dati;
  • usare memoria, localStorage, JSON, database o API;
  • convertire dati se serve;
  • nascondere dettagli tecnici agli altri livelli.

All’inizio useremo un archivio in memoria.

Poi lo sostituiremo con localStorage o JSON.

Il punto e preparare la sostituzione senza riscrivere dominio e casi d’uso.

Flusso di una operazione

Disegna RegistraPrestito cosi:

Utente
  -> Presentation
      legge form e crea comando
  -> Application
      trova strumento
      verifica regole
      crea prestito
      salva modifiche
  -> Domain
      decide se lo strumento e prestabile
      crea prestito valido
  -> Infrastructure
      legge e salva strumenti e prestiti

Il disegno non deve essere perfetto.

Deve farti vedere se una responsabilita e nel livello giusto.

Cosa non vogliamo piu

Nel programma fragile avevamo spesso:

main.js
  legge input
  valida regole
  crea oggetti
  salva in localStorage
  aggiorna HTML
  mostra messaggi

Questo file aveva troppe responsabilita.

Il primo taglio architetturale serve a spezzarlo.

Esercizio

Prendi queste responsabilita e mettile nel livello corretto:

1. Mostrare "Prestito registrato".
2. Verificare che uno strumento guasto non venga prestato.
3. Salvare strumenti in memoria.
4. Recuperare lo strumento prima di registrare il prestito.
5. Leggere il valore di inputNome.
6. Creare un prestito valido.
7. Filtrare strumenti per stato.
8. Convertire un errore in messaggio utente.

Possibile soluzione:

1. Presentation
2. Domain
3. Infrastructure
4. Application
5. Presentation
6. Domain
7. Application
8. Presentation

Cosa produrre

Alla fine della lezione devi avere:

  • un disegno dei quattro livelli;
  • una tabella responsabilita -> livello;
  • un flusso disegnato per RegistraPrestito;
  • almeno tre responsabilita da spostare fuori dal file principale;
  • una foto, uno screenshot o un file Markdown con la mappa.

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 disegnare i quattro livelli del progetto, il punto centrale è questo: Refactoring significa cambiare la struttura senza cambiare il comportamento visibile. È un lavoro lento, controllato e protetto da verifiche.

Il rischio tipico è riscrivere tutto perché il codice non piace. Nel laboratorio il refactoring deve insegnare disciplina: piccoli passi, programma funzionante, verifica dopo ogni passo. 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. Scegli un solo problema di struttura.
  4. Scrivi o esegui una verifica prima di modificare.
  5. Estrai una responsabilità alla volta.
  6. Rileggi il diff e controlla che il comportamento sia invariato.
  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:

// Prima: una funzione fa tutto.
// Dopo: il flusso diventa leggibile.
const comando = leggiInput();
const esito = eseguiCasoUso(comando);
salvaSeNecessario(esito);
mostraEsito(esito);

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 spiegare i quattro livelli con esempi del registro;
  • so dove sta una regola di dominio;
  • so dove sta un caso d’uso;
  • so dove sta il salvataggio;
  • so cosa deve fare la UI;
  • ho una mappa utile per spostare i file.

Nella prossima lezione trasformiamo la mappa in cartelle minime.