modulo 10 di 24 / Ore 21-40

Moduli 9-16 / Checkpoint 40 ore

Mapping: trasformare DTO in dominio e dominio in DTO

Scrivere funzioni di mapping per convertire dati salvati in oggetti di dominio e oggetti di dominio in dati salvabili.

30 min Architettura del software

Mapping: trasformare DTO in dominio e dominio in DTO

Mapping significa trasformare un oggetto da una forma a un’altra.

Nel nostro progetto:

dominio -> DTO
DTO -> dominio

Il mapping e importante per non lasciare che localStorage, JSON o API decidano la forma del dominio.

Obiettivo

Alla fine devi avere:

  • funzione da Strumento a StrumentoDTO;
  • funzione da StrumentoDTO a Strumento;
  • funzione equivalente per Prestito;
  • una idea chiara di dove mettere il mapping.

Dove mettere il mapping

Il mapping tra formato salvato e dominio sta in Infrastructure.

Esempio:

src/infrastructure/mappingStrumento.js
src/infrastructure/mappingPrestito.js

Perche?

Perche riguarda la conversione verso un formato esterno.

Il dominio non deve sapere da dove arriva il DTO.

Mapping semplice

Se DTO e dominio hanno la stessa forma:

export function strumentoToDto(strumento) {
  return {
    id: strumento.id,
    nome: strumento.nome,
    categoria: strumento.categoria,
    stato: strumento.stato,
  };
}

export function dtoToStrumento(dto) {
  return {
    id: dto.id,
    nome: dto.nome,
    categoria: dto.categoria,
    stato: dto.stato,
  };
}

Sembra inutile.

Ma crea un punto esplicito dove cambiare se il formato esterno cambia.

Mapping con nomi diversi

Esempio API:

export function dtoToStrumento(dto) {
  return {
    id: dto.id,
    nome: dto.name,
    categoria: dto.category,
    stato: mappaStatoDaApi(dto.status),
  };
}

E inverso:

export function strumentoToDto(strumento) {
  return {
    id: strumento.id,
    name: strumento.nome,
    category: strumento.categoria,
    status: mappaStatoVersoApi(strumento.stato),
  };
}

Il resto dell’applicazione continua a usare nome, categoria, stato.

Validare durante il mapping

Quando trasformi DTO in dominio, puoi usare funzioni del dominio:

import { creaStrumento } from "../domain/strumento.js";

export function dtoToStrumento(dto) {
  return creaStrumento({
    id: dto.id,
    nome: dto.nome,
    categoria: dto.categoria,
    stato: dto.stato,
  });
}

Questo e utile per evitare che dati corrotti entrino nel dominio.

Attenzione: se localStorage contiene dati vecchi, questa funzione puo lanciare errori.

Li gestiremo nella prossima lezione.

Mapping di Prestito

export function prestitoToDto(prestito) {
  return {
    id: prestito.id,
    strumentoId: prestito.strumentoId,
    assegnatario: prestito.assegnatario,
    apertoIl: prestito.apertoIl,
    chiusoIl: prestito.chiusoIl,
    stato: prestito.stato,
  };
}

export function dtoToPrestito(dto) {
  return {
    id: dto.id,
    strumentoId: dto.strumentoId,
    assegnatario: dto.assegnatario,
    apertoIl: dto.apertoIl,
    chiusoIl: dto.chiusoIl ?? null,
    stato: dto.stato,
  };
}

Se hai una funzione di dominio per creare o chiudere prestiti, usa quella quando ha senso.

Non forzare una funzione di creazione se rende impossibile leggere uno storico legittimo.

Mapping dentro l’archivio

L’archivio localStorage puo usare il mapping:

function leggiStrumenti() {
  const dtoList = JSON.parse(localStorage.getItem(CHIAVE_STRUMENTI) ?? "[]");
  return dtoList.map(dtoToStrumento);
}

function scriviStrumenti(strumenti) {
  const dtoList = strumenti.map(strumentoToDto);
  localStorage.setItem(CHIAVE_STRUMENTI, JSON.stringify(dtoList));
}

Il caso d’uso continua a ricevere oggetti di dominio.

Non DTO.

Esercizio

Scrivi quattro funzioni:

strumentoToDto
dtoToStrumento
prestitoToDto
dtoToPrestito

Poi verifica con esempi:

## Mapping Strumento

Dominio iniziale:

DTO ottenuto:

Dominio ricostruito:

Differenze:

Cosa produrre

Alla fine della lezione devi avere:

  • file di mapping per strumenti;
  • file di mapping per prestiti;
  • archivi localStorage che usano il mapping o una nota su dove lo useranno;
  • almeno due esempi di conversione;
  • una nota su cosa succede se il DTO e incompleto.

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 mapping: trasformare DTO in dominio e dominio in DTO, 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

  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. Distingui modello di dominio e formato salvato.
  4. Crea una funzione di mapping leggibile.
  5. Gestisci dati mancanti o non validi.
  6. Verifica che i casi d’uso non cambino quando cambi archivio.
  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:

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 cosa fa il mapping;
  • so convertire dominio in DTO;
  • so convertire DTO in dominio;
  • il caso d’uso non riceve DTO esterni;
  • so dove cambiare se il formato JSON cambia.

Nella prossima lezione gestiamo dati mancanti, vecchi o corrotti.