2010-04-16 13 views
10

Continuo a lottare con il modello MVVM e, nel tentativo di creare un progetto pratico per un progetto di piccole/medie dimensioni, ho incontrato una serie di sfide. Una di queste sfide è capire come ottenere i vantaggi del disaccoppiamento con questo modello senza creare un sacco di codice ripetitivo e difficile da gestire.MVVM: Thin ViewModels e Rich Models

La mia strategia attuale è stata quella di creare classi modello "ricche". Sono pienamente consapevoli del fatto che saranno consumati da un pattern MVVM e implementeranno INotifyPropertyChanged, permetteranno che le loro collezioni vengano osservate e rimarranno consapevoli del fatto che potrebbero essere sempre sotto osservazione. Le mie classi ViewModel tendono ad essere sottili, esponendo solo le proprietà quando i dati devono essere trasformati, mentre la maggior parte del loro codice è RelayCommand handler. Le visualizzazioni si associano felicemente a ViewModels o Models direttamente, a seconda che sia necessaria una trasformazione dei dati. Uso AOP (tramite Postsharp) per alleviare il dolore di INotifyPropertyChanged, rendendo semplice rendere tutte le mie classi Model 'ricche' in questo modo.

Ci sono degli svantaggi significativi nell'utilizzo di questo approccio? Posso presupporre che ViewModel e View siano così strettamente accoppiati che se ho bisogno di una nuova trasformazione dei dati per la vista, posso semplicemente aggiungerlo al ViewModel secondo necessità?

risposta

6

Penso INotifyPropertyChanged del modello è utile solo quando sei in attesa di essere operati dal vostro VM e "forze" esterne contemporaneamente.

Sono personalmente un sostenitore dei modelli POCO. Mettere qualsiasi impalcatura specifica del framework nel mio modello mi farebbe preoccupare. Quando si inserisce un evento nella classe del modello, è necessario considerare attentamente possibili problemi relativi al ciclo di vita, alla serializzazione, alla memorizzazione del modello ecc. Ad esempio, cosa succede se si ricrea l'oggetto dall'origine dati e le vecchie sottoscrizioni INotifyPropertyChanged non sono più valide?

Analogamente posto migliore per ObservableCollection è nella VM, che può consumare un'origine dati IEnumerable, e presentare alla sola visualizzazione selezionato o ad hoc elementi filtrata.

+0

Le 'forze esterne' sono una buona descrizione di come funziona attualmente il mio disegno. La mia VM sta trasformando il Modello (se necessario) per la Vista, ma il Modello può essere interpretato dalla VM, da altri Modelli o da una VM completamente diversa che interagisce con essa in un modo diverso. Se un'estensione dello strumento aggiunge un cavo nel mio modello, mi piacerebbe che tutte le mie macchine virtuali e le mie viste guardassero il cablaggio per vedere la modifica. Ho creato raccolte personalizzate che monitorano il modello ObservableCollections per fornire filtri speciali (oltre al solo filtro CollectionView), ma il più delle volte mi collego al modello ObservableCollection. –

3

Ritengo che questo sia l'approccio pragmatico: abbiamo seguito questo schema con successo in passato.

La premessa di base era quella di collegarsi direttamente a un modello che implementa INotifyPropertyChanged per la maggior parte dei dati di sola lettura e quindi aggiungere proprietà extra al viewmodel per le informazioni specifiche che devono essere trasformate (come suggerito). Per le proprietà non di sola lettura, abbiamo trovato più semplice la creazione di voci viewmodel (generalmente di tipo string) in quanto ciò consente di aggiungere facilmente la convalida lato client nel viewmodel.

+2

Avete la transizione ad un modello diverso ora?Ci sono state cose specifiche che hai appreso come risultato di questo precedente approccio che suggeriva la necessità di cambiare il tuo approccio? –

0

Sono d'accordo che ci sarà un accoppiamento stretto tra View e ViewModel. Ma questo può essere alleviato in una certa misura usando IValueConverters quando possibile per fare delle trasformazioni.

Cerco di mantenere la mia logica aziendale nel mio ViewModel. Inoltre, utilizzo Viewmodel per modificare la forma del mio modello per adattarlo a ciò che la vista potrebbe aspettarsi.

+1

questo sembra molto sbagliato ... – vidalsasoon

3

Disclaimer - io non sono un esperto -

non metto INotifyChanged sui miei modelli. Avevo fatto questo in un primo momento, ma è venuto alla semplice realizzazione che INotifyChanged è in realtà solo pratico per notificare l'interfaccia utente così ho messo solo INotifyChanged sul mio ViewModel ora. Questo ha reso più facile per controllare il numero di "RaisePropertyChanged" ... Le mie opinioni non fanno riferimento direttamente una modella.

sto lavorando al mio primo progetto MVVM ancora sulla mia 3a maggiore refactoring: P