Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

ViewModel != Model

Sfruttare il pattern DTO per creare viste fortemente tipizzate
Sfruttare il pattern DTO per creare viste fortemente tipizzate
Link copiato negli appunti

Nello sviluppo di applicazioni MVC viene spontaneo chiedersi cosa si intenda per Model e se sia incombenza del presentation layer essere responsabile del suo aggiornamento. Effettivamente in applicazioni n-layer in cui il design del sistema ha separato le responsabilità applicative tra varie isole funzionali, il model, il suo aggiornamento e la sua eventuale persistenza non sono responsabilità del client.

In un'applicazione abbastanza articolata alcune entità del nostro dominio possono essere complesse, ma la loro complessità potrebbe riguardare solo in parte le viste che la espongono all'utente. Pensiamo al classico utente del nostro e-commerce: l'entità in questione, chiamiamola User, potrebbe avere molti dati anagrafici, potrebbe essere legata ad altre entità come i prodotti acquistati, i commenti lasciati, i prodotti preferiti, ecc.

Pensiamo adesso alla vista dell'applicazione che permette la sua autenticazione: ci servono probabilmente solo user id e password, non tutta l'anagrafica e nemmeno i legami con le altre entità. In questo caso usare l'entità di dominio come model per la nostra operazione di login è sicuramente sovradimensionato, anche se facciamo in modo di caricarne solo i dati necessari.

Supponiamo poi che lo stesso utente debba eseguire un ordine e che in fase di registrazione non abbia specificato, perché non obbligatorio, l'indirizzo a cui spedire i suoi prodotti: è giusto, perché viste diverse, in questo caso registrazione e ordine, usano la stessa entità ma con regole di validazione differenti.

Per risolvere questi problemi è possibile usare degli oggetti creati appositamente, completamente anemici, che quindi espongono solo struttura da usare come contratto con il layer che ci fornisce le informazioni di cui necessita la nostra vista, nel caso del login avremmo un oggetto del tipo:

public class UserLoginDTO
{
    public string UserId { get; set; }
    public string Password { get; set; }
}

Il nome dato alla classe indica anche il nome del famoso design pattern utilizzato per lo scambio dati utilizzato risolvere i problemi di cui abbiamo discusso: Data Transfer Object (DTO). L'insieme dei DTO scambiati con lo strato di servizi può definire il nostro model se non rilassiamo troppo i vincoli di tale pattern:

  1. Un DTO per ogni vista e per ogni client
  2. Classi completamente anemiche (non implementano metodi)
  3. Solo le proprietà strettamente necessarie alla view

L'obiezione più ovvia è sicuramente: "ma in questo modo passiamo la vita a scrivere DTO?". La mia risposta è sempre: "Sì, ma probabilmente faremo solo quello!". Questo perché grazie ai framework a nostra disposizione e grazie al fatto che un DTO è unico e progettato per una determinata vista possiamo indicare in questa classe le regole di validazione e le informazioni di rendering semplicemente decorando le varie property con semplici attributi, nel caso del framework MVC possiamo sfruttare la potenza delle Data Annotation:

public class UserLoginDTO
{
    [DisplayName("Nome Utente")]
    [Required(ErrorMessage="L'identificativo dell'utente è obbligatorio")]
    public string UserId { get; set; }
    [Required(ErrorMessage = "La password è obbligatoria!")]
    public string Password { get; set; }
}

Il nostro model a questo punto è rappresentato dall'insieme dei DTO, che useremo per creare le nostre pagine strongly typed:

Figura 5. Form di creazione di view strongly-typed
Form di creazione di view strongly-typed

Un DTO utilizzato in questo modo viene spesso detto ViewModel proprio ad indicare che non si tratta del Domain Model. Naturalmente siate pragmatici: se dovete rispondere a requisiti *veri* di scalabilità, manutenibilità e testabilità l'uso dei DTO, come tutti i design pattern, può aiutarvi a separare le responsabilità.

Figura 6. Vista creata
Vista creata

Ti consigliamo anche