In un esempio così semplice, questa risposta sarebbe sì (è irragionevolmente ridondante). Ma, presumibilmente, una pagina conterrà più di un semplice oggetto Modello. Si può avere lo stato della pagina così come più altri oggetti del modello che devono essere tutti tracciati. Questo è fatto nel ViewModel.
Ad esempio, è possibile avere ulteriori informazioni sull'utente connesso visualizzato in una barra di stato, nonché un servizio in esecuzione per rilevare le modifiche a un file di testo.
È anche possibile disporre di un modulo per la modifica dell'oggetto Studente. Se si intende convalidare tali modifiche, non si desidera modificare direttamente l'oggetto Studente fino a dopo la verifica delle modifiche. In tal caso, ViewModel può fungere da posizione di archiviazione temporanea.
Nota su quanto sopra: Non è insolito che la convalida si verifichi nel modello, ma anche in questo caso è probabile che l'utente possa immettere valori non validi mentre è in corso la modifica di un modulo. Ad esempio, se il tuo modello non consente un valore di lunghezza zero in un campo, desideri comunque consentire all'utente di eliminare il valore, spostarlo in un altro campo (ad esempio, per copiarlo), quindi tornare al campo e terminare la modifica (incolla). Se sei legato direttamente al modello, la tua logica di convalida potrebbe non gestire questo stato "intermedio", "non ancora finito" come desideri. Ad esempio, potresti non voler accostare il tuo utente con errori di convalida fino a quando non hanno finito e fatto clic su "Salva".
Probabilmente avrete anche oggetti Command nel ViewModel per gestire i clic sui pulsanti e simili. Questi sarebbero oggetti specifici del dominio che sarebbero inutili in un modello.
ViewModels sono utili anche quando è necessario filtrare o modificare temporaneamente "oggetti modello" per ottenere qualcosa di utile sullo schermo. Ad esempio, potresti voler visualizzare un elenco di tutti gli utenti in un sistema insieme a un elenco in tempo reale dei primi dieci esecutori tra loro (aggiornato ogni 10 secondi). Oppure potresti voler mostrare un elenco di Report e un grafico che mostra la percentuale complessiva di utilizzo, ecc. Filtraggio, ordinamento e personalizzazione di tali dati all'interno di ViewModel.
Il modello, d'altra parte, è tipicamente il più puro possibile. Idealmente, si desidera solo POCOs che (di solito) modellino esattamente ciò che si trova nella memoria persistente (database o cosa si ha). Se la tua memoria persistente ha i campi FirstName e LastName, anche il tuo Modello. Solo nel tuo ViewModel le combinerai per ottenere un campo Nome (o "Primo Ultimo" o "Ultimo, Primo" a seconda delle necessità della Vista).
Ad esempio:
namespace Model
{
public class Student
{
public string FirstName { get; set; }
public string LastName { get; set; }
}
public class Class
{
public string Name { get; set; }
public float Score { get; set; }
}
}
namespace ViewModel
{
public class EditStudentRecordViewModel
{
private Model.Student _student;
private IEnumerable<Model.Class> _studentClasses;
/* Bind your View to these fields: */
public string FullName
{
return _student.LastName + ", " + _student.FirstName;
}
public string FirstName { get; set; }
public string LastName { get; set; }
public IEnumerable<Model.Class> PassingClasses
{
get
{
return _studentClasses.Where(c => c.Score >= 78);
}
}
public IEnumerable<Model.Class> FailingClasses
{
get
{
return _studentClasses.Where(c => c.Score < 78);
}
}
public void Save()
{
List<string> l_validationErrors = new List<string>();
if (string.IsNullOrEmpty(this.FirstName))
l_validationErrors.Add("First Name must not be empty.");
if (string.IsNullOrEmpty(this.LastName))
l_validationErrors.Add("Last Name must not be empty.");
if (l_validationErrors.Any())
return;
_student.FirstName = this.FirstName;
_student.LastName = this.LastName;
Model.Utilities.SaveStudent(_student);
}
}
}
Domanda molto buona, tra l'altro: chiara, concisa e contiene codice di esempio. – JDB