In questi giorni sto studiando a fondo il pattern M-V-VM ((Data)Model-View-ViewModel), visto che quando fu introdotto per la prima volta (ormai 3 anni fa) non lo valutai affatto positivamente poiché ero convinto che avrebbe "sporcato" troppo il pattern MVC, creando confusione sia tra gli sviluppatori che tra gli architects.
Questo pattern fu coniato nel 2005 da John Gossman mentre WPF vedeva la luce (Avalon). In uno dei suoi post a riguardo, Gossman lo definì nella seguente maniera:
Model/View/ViewModel is a variation of Model/View/Controller (MVC) that is tailored for modern UI development platforms where the View is the responsibility of a designer rather than a classic developer....The Model is defined as in MVC...The View consists of the visual elements... The ViewModel can be thought of as abstraction of the view, but it also provides a specialization of the Model that the View can use for data-binding. In this latter role the ViewModel contains data-transformers that convert Model types into View types, and it contains Commands the View can use to interact with the Model.
A seguito di un'analisi più attenta, devo dire che ho modificato la mia posizione iniziale, soprattutto considerando che in linea teorica il pattern M-V-VM può essere utilizzato congiuntamente al pattern MVC ( MVC + VM ). D'altronde, il fatto che si possieda o meno un ViewModel è ortogonale al fatto che si possieda o meno un Controller.
Il ViewModel infatti può assumere due ruoli:
- un livello di astrazione per la View
- una specializzazione del (Data)Model che la View utilizza per il DataBinding (tramite una trasformazione dei tipi del Model nei tipi della View) e che contiene i Commands che la View può usare per interagire con il Model
Da una parte, gli aspetti che mi piacciono di questo pattern architetturale sono quelli che lo rendono più vicino ad un "WPF-friendly wrapper" del pattern MVC:
- supporto totale al two-way databinding offerto da WPF (dati da-verso la View)
- maggiore semplificazione/flessibilità dello sviluppo di un' applicazione WPF di qualità (SoC) rispetto a soluzioni MVP (già affermate in particolar modo su Windows Forms e ASP.NET) o MVC (ragazzi ASP.NET MVC è perennemente in Beta :D !!!).
...Dall'altra mi ritrovo a riflettere su alcuni punti critici di tale pattern che potrebbero minacciare seriamente lo sviluppo di applicazioni enterprise:
- In scenari complessi potrebbe essere estremamente difficile progettare un ViewModel che risponda al giusto livello di generalità (ricordiamoci che il ViewModel ingloba Proprietà, Astrazioni del DataModel (ObservableCollection), una sfilza di ICommand, Change Notification via INotifyPropertyChanged etc..)
- Il miracoloso meccanismo dichiarativo di DataBinding non è facile da debuggare quanto il classico approccio imperativo. E' anche vero che una semplice scappatoia per difficoltà di questo tipo rimane pur sempre l'intercettazione degli eventi che ci servono sia lato View che lato ViewModel.
- Poiché un DataBinding dietro le quinte alloca delle risorse di "book-keeping" (contabilità :D), se si implementano pesanti scenari di MultiBinding (in cui uno stesso oggetto è associato a più componenti dell'UI) si possono ottenere situazioni in cui i Binding sono addirittura più pesanti degli oggetti bindati!!! E' sicuramente difficile che si presenti un caso di questo tipo in un' applicazione reale, ciò non toglie che un occhio alle performance dovremmo sempre darglielo.
In questo post di Karl Shifflett ho trovato interessante questa immagine che evidenzia tutte le caratteristiche di un' architettura M-V-VM in un contesto LOB. I concetti ci sono praticamente tutti... ora sta a noi portarli in vita :D
Technorati Tag:
WPF,
M-V-VM