суббота, 5 апреля 2008 г.

DataModel-View-ViewModel in WPF. Part 1 DataModel.

All of my UIs are built on very powerful pattern called DataModel-View-ViewModel (DM-V-VM) that was first described by Dan Crevier. I've written a small "framework" (I better say set of classes) to enhance it to my needs.

We have chosen a WPF UI framework in conjuction with the Composite Application Block (CAB) and SmartClient Software Factory (SCSF) to be the foundation of the presentation layer for the project. CAB stimulates and actively using another two UI patterns Model-View-Controller (M-V-C) and Model-View-Presenter (M-V-P). So my set of classes is an extension to an existing infrastracture that uses some of the built-in CAB functionality, especialy IoC-container to resolve dependencies of my classes.

DM-V-VM pattern is a special case of another more brief UI pattern - M-V-P. Martin Fowler calls it the PresentationModel. There is one problem with this pattern - it is fantastic in WPF, but you won't be able to switch to another UI technology without rewriting some code (you can read some on this in Dr.WPF blog). And if it is an evil you can live with than this pattern will be the best choice. And may be it will become too complex to maintain your code when you will have more then 5 data sources. In this case I would recomend you to switch to the M-V-P pattern.

So let's go on.


Classes that provide data (business objects). Their duty is to provide data in WPF-friendly way (at least to implement INotifyPropertyChanged). All the properties and some of methods should only be accessed from UI thread, and it is strongly recommended not to block the UI thread for long.
I think that DM classes (as they were described by Dan Crevier) perfectly fits SOA way of programming, being a data gateway from services to UI.
But services are not the only possible source of data, it can be anything - a file in a file system, for example. To make DM classes lossely-coupled with this different data sources there are providers system that is delegated to obtain data (a strategy by GoF).
A foundation for my DM classes is the Dan Crevier's implementation of DM-V-VM pattern so I shall concentrate on my enhancments instead of rewriting code here.
  1. The first thing to come is the base interface for DM classes with the couple of inherited generic interfaces that are narrows (or should I say precises) DM functionality by restricting Entity and Provider types.
  2. The second thing is the typed provider interface.

  3. Base DM class is the third thing. It contains a bunch of asyncronous methods (load complete notification, exception catched notification, etc.) plus a set of virtual methods to be overriden in descendant classes.

Invention of generic provider enabled me to write generic DM class that is parameterized with an entity type and typed provider (typed by entity type). I've called it SingleEntityModel. This class frees you from writing lots of DM descendants with the only duty to provide some Entity.

All the clients work with the DM objects through their interfaces as they are treated as a local services and can be injected in dependent code by an IoC-container.
That is all on DataModel, check for new parts.
Good luck!
PS: I will include code in a later parts.

Комментариев нет: