The formal ModelViewViewModel pattern defines only 3 parts, the “View” and “ViewModel” are clearly defined and the rest we simply call “Model”. Is this enough? Absolutely not. There is a lot more to worry about than simply separating the visuals from code!
When building a composite application it’s vital to assign well define the responsibilities on each part and then stick with the rules you have defined.
I call the pattern “Model+” since in this case the Model has being well defined. So from this paper don’t expect anything special about the “View”-“ViewModel” pair. We all think we understand this one; the “Model” part is the key were all the problems arise!
The following design addresses many scenarios in a composite application. It’s simply one design, nothing more. You can find the source code with a sample application under: https://bakopanos.googlecode.com/svn/trunk/prism
The sample is a modified version of the original sample that ships with the Prism quickstarts.
The sample is a modified version of the original sample that ships with the Prism quickstarts.
Controller
The controller is responsible to create views and position the views on the appropriate placeholders. For example if you are using Prism (Composite WPF) these placeholders are called Regions and there is a RegionManager and a RegionRegistry to deal with regions. Another concern that the controller has is to activate views. For example activate the tab page in a tabstrip that contains the view you would like to show. It's appropriate to say that the controller orchestrates the User Interface Process.
It’s important to make sure that you decouple UIP from all the rest. This is the reason that an eventaggregator comes very handy here. The controller can subscribe to strongly types events and get notified about changes in the state. Typically in most cases this will be notification about selected item in a workflow or dirty items.
View
In order to implement correctly the Model-View-ViewModel pattern (Fowler: PresentationModel) you really need to restrict the View to only the visuals. The Passive View doesn’t require any unit testing and the visual designer can work decoupled from the developer.
ViewModel
When I think about ViewModels I really see them as facades. I am aware that most people see workflows as the place where all logic goes; the problem is that if you put too much in a ViewModel then better consider a ModelViewController approach. What I see sometimes is ViewModels being sub classed in order to allow reuse. To my understanding this is by definition wrong. A ViewModel should simply aggregate all that the view needs to display and provide them to the view in a simple structure. You can also have logic there that has to do with the current view, but nothing more.
WorkItem
The work item is the key to a composite application. Why? Because the workitem is where you store your state. Let’s consider an example: Your application should change to the current customer. In other words after you select the customer in a list box, anything that you do in any screen should consider that specific customer. So if you get a bug assigned to you that somewhere in the application the customer is not displayed properly, where is the place where you first look? What part of your architecture remembers that? To my understanding this should be the WorkItem. The ViewModel binds the selected item to the workitem, and when the selected item changes the workitem publishes an event. The interested controllers register for that event and drive in turn any UIP.
Services
BEWARE: services should be stateless. This is very important. If you would like your application to be easily changed and tested then model anything that has to do with state in a WorkItem.
There are two categories of services:
· Infrastructure Services, basically cross-domain functionality. Example ILogService
· Services, that interact with the business/service layer in order to support the application with domain specific functionality. Example IProjectService

This comment has been removed by the author.
ReplyDeleteThis is just what I've been looking for since I started with MVVM. I'm used to designing projects with UML and I could easily plan a project right down to its unit tests using that method. I made the switch from WinForms to MVVM and I could see the benefits, but there were still many things lacking. This article finally shed some light on those issues. Thanks a lot. Hope to see another article from you soon, preferably something that integrates a Business and/or Data Access Layer. Keep up the good work.
ReplyDelete