2011-02-01 13 views
24

So che potrebbe essere brutto usare i modelli di dominio come modelli di vista. Se il mio modello di dominio ha una proprietà denominata IsAdmin e ho un'azione Crea controller per creare utenti, qualcuno potrebbe modificare il mio modulo e portarlo a POST a IsAdmin = valore del modulo vero, anche se non ho esposto un campo di testo simile nella mia vista . Se sto utilizzando il modello di associazione, allora quando ho commesso il mio modello di dominio, quella persona ora sarebbe un amministratore. Quindi la soluzione diventa esposta solo le proprietà di cui ho bisogno nel modello di visualizzazione e utilizzando uno strumento come AutoMapper per mappare i valori delle proprietà del mio oggetto modello di visualizzazione restituito a quello dell'oggetto modello dominio. Ma ho letto che l'attributo bind su una classe può essere usato per istruire il Model Binder su quali proprietà dovrebbe e non dovrebbe vincolare. Quindi, qual è la ragione per cui si creano due classi separate (modello di dominio e modello di vista) che rappresentano essenzialmente la stessa cosa e poi si incurvano in modo eccessivo nel mapparle? È più un problema di organizzazione del codice e se sì, come sto beneficiando?Perché due classi, modello di vista e modello di dominio?

EDIT

Una delle ragioni più importanti che ho incontrato per una vista del modello che è separata dal modello di dominio è la necessità di implementare il modello MVVM (basato sul modello PM di Martin Fowler) per la gestione interfacce utente complesse.

+1

Dai un'occhiata anche a questa domanda http://stackoverflow.com/questions/3094633/bestpractice-mixing-view-model-with-domain-model –

risposta

18

Ho scoperto che mentre il mio modello di dominio mi ottiene l'85% del modo di avere i campi che voglio, non ha mai coperto il 100% dei valori che voglio dalla mia vista. Soprattutto quando si tratta di autorizzazioni e se un utente debba o meno avere accesso a determinate parti della vista.

Il concetto di design che cerco di seguire è quello di avere il minimo di logica nelle mie opinioni possibile. Ciò significa che ho campi nel mio modello di visualizzazione come "CanViewThisField" o "CanEditThisField". Quando ho iniziato per la prima volta con MVC avrei il mio modello di dominio come modello di visualizzazione e mi sono sempre imbattuto nello scenario in cui avevo bisogno di uno o due campi in più per rendere la mia vista meno disordinata. Da allora sono passato al percorso View Model/Model Builder e ha funzionato magnificamente per me. Non combatto più il mio codice, ma sono in grado di migliorare il mio modello di visualizzazione di cui ho bisogno senza influenzare il modello di dominio.

+0

Sono d'accordo con rendere la vista meno ingombrante ma non potremmo astrarre questo tipo di funzionalità per il modello di dominio invece del modello di visualizzazione? L'ho detto prima ma non potrei usare una funzione DisplayAddress() sul mio modello di dominio che combinerebbe le proprietà del dominio come Indirizzo, Città, Stato e Zip? Il db mappa solo le proprietà non funzioni. – enamrik

+0

Ovviamente tutto è possibile, dipende solo da che parte vuoi andare. Ho generato il mio modello di dominio per me, quindi non toccherò davvero quel codice. Se stai usando qualsiasi tipo di ORM, allora è il caso. Il modello di visualizzazione ha permesso la massima flessibilità per me senza compromettere le prestazioni. –

+0

Scusa ma non ho seguito il link che hai dato fino ad ora. Ho concluso che decidere se prendere o meno il percorso del modello di modello di dominio dipende dalle richieste del modello di dominio. Posso vedere come alcuni dei miei oggetti del modello di dominio utilizzerebbero un modello di visualizzazione mentre altri non lo faranno (anche se ciò potrebbe confondere qualcuno - ci penserò di più). Ad ogni modo, ho la mia risposta. Grazie a tutti! – enamrik

2

A volte è necessario visualizzare i dati in un modo specifico (ad esempio, visualizzare una data nel formato mm/gg/aaaa vs aaaa/mm/gg) e spesso è più facile rendere questa proprietà nella vista e non nel modello di dominio, dove si dovrebbe (o si dovrebbe) avere una mappatura di una colonna nel proprio db.

+0

Grazie, è logico. Ma ancora, non potremmo semplicemente creare funzioni sul modello di dominio per fare ciò? Come DisplayAddress() che combinerebbe le proprietà del dominio come Indirizzo, Città, Stato e Zip? Il db mappa solo le proprietà non funzioni. Questa idea è una violazione di qualche filosofia di design? – enamrik

+0

In un certo senso, sì. Potresti fare tutto questo nel modello di dominio se lo volessi e funzionerebbe allo stesso modo. Tuttavia, non ho mai visto che funzioni molto bene da una manutenzione. In genere, ho visto questo tipo di cose inserite nel modello di visualizzazione (o in qualsiasi modello di presentazione che si sta utilizzando). Quindi, in realtà, è solo un problema organizzativo che altro. :) – khr055

15

Un altro buon motivo per avere un ViewModel è il paging di grandi serie di dati. È possibile passare la vista a un array di Persona (Person[]) ma i metadati come il numero di pagine, il numero della pagina corrente, la dimensione della pagina non appartengono alla classe Person.

Pertanto, PersonListViewModel risolverebbe questo problema.

+1

Questo è un ottimo esempio. – Wuaner

+0

grazie! :-) –

2

A ViewModel contiene solo i membri richiesti dalla vista. Di solito possono essere pensati come una semplificazione o un "appiattimento" del modello di dominio sottostante.

pensare a loro in questo modo:

  • ViewModel: questo è il dato che è appropriato per rendere questo vista
  • modello di dominio: tutto questo è l'informazione la mia applicazione ha bisogno su questa entità al fine di eseguire tutte le sue funzionalità

Ad esempio, la mia classe di ordine ha un membro chiamato Cliente che è un'associazione composition, ovvero, il mio ordine ha un cliente. Questo oggetto Cliente ha membri come Nome, Cognome, ecc ... Ma come visualizzarlo in una vista "dettagli" dell'ordine o in un elenco di Ordini e Clienti che li hanno inseriti?

Bene, utilizzando un ViewModel posso avere un OrderListItemViewModel che ha un membro CustomerName e posso mappare la combinazione di Nome e Cognome dall'oggetto Cliente a questo. Questo può essere fatto manualmente, o molto preferibilmente usando Automapper o simili.

Utilizzando questo approccio, è possibile avere più ViewModels ordine specifici per diverse viste, ad es. la vista elenco ordini potrebbe rendere il nome del cliente in un modo diverso rispetto alla vista Dettagli ordine.

Un altro vantaggio di ViewModels è che è possibile ridurre i dati estranei non richiesti dall'oggetto dominio sottostante su una vista, ad es. se visualizzo un elenco di ordini, desidero davvero visualizzare tutte le informazioni di contatto del cliente, i dettagli di fatturazione, ecc.? Immagino che ciò dipenda dallo scopo della lista ma, probabilmente no.

2

È necessario ricordare che il vostro domain model classes sono usati solo internally; cioè, non vengono mai inviati al client . Questo è ciò per cui vengono utilizzati i tipi di modello di servizio (Visualizza i tipi di modello): rappresentano i dati che andranno avanti e indietro tra il client e il servizio.