Model-View-Presenter View-Model (MVPVM)

!!NEW!! See authored MSDN article on topic on the following link:
http://msdn.microsoft.com/en-us/magazine/hh580734.aspx

The MVP-VM pattern is the necessary evolution of the Model-View-Presenter pattern for the WPF and Dependency Injection environment.   It is a combination of MVP and MVC’s Application Model (Application Model is also known as Presentation Model and MVVM[1])

MVPVM

Presentation Layer

The Triad components (View Model-View-Presenter) that the user will interface with

Model

The model is your data structures, databases and tables.   These could reside in SQL servers, files or in the cloud.   Where the model structures will be globally available to all layers the actual data is only available via the Data Access Layer (DAL)

Data Access Layer (DAL)

The DAL should be the only interface to your model.   Classes and methods used to access the data will reside at this layer.   Ideally your DALs will have a clear separation of concerns, i.e., only do one job and do it well.  For example a SQL DAL will only process SQL queries, an XML File DAL will process XML queries against files and an XML Web DAL against Web Services as applicable.   DALs will only return object references from the Domain within scope of all layers, i.e. WCF services calls return data that is only within scope of the DAL that is consuming the service, it must transfer this data, via Data Transfer Objects (DTO) to structures within the scope of the application.

It is easy, and quite common, to have your presentation layer access the model directly.   This is not extensible and will require you to update “all” presentation layer components when interface changes occur to the data, i.e., a field is removed.    A DAL is the only layer that is required to know about changes.  For example it could provide dummy data for the field that is no longer used by the system.   Programmers will have to remove references to the field as but it won’t break any of the existing applications that rely on it – the work can be prioritized as applicable.

Business Logic Layer (BLL)

The business logic layer is the only layer that should be consuming your DAL .   It doesn’t concern itself with specifics of data access, e.g., doesn’t care about file connections, SQL statements or XML queries to be executed by the the DAL.   It simply request objects from the DAL based on an established interface (contract).

This is particularly important for Dependency Injection since application configuration could easily swap out a DAL without the BLLs knowledge.  For example your IT team notifies you that it will be swapping out your SQL Server with a Cloud Server in six months.  The current application configuration looks as follows:

       container.Register<IFinanceData, SqlFinanceDal>()

Which the BLL will use as follows:
var financeDal = container.Resolve<IFinanceData>();
       var dataList = fianceDal.GetFinancialDataForGroup(groupId);
var isValid =  ValidateData(dataList, out dataException)
if(!isValid)
throw new InvalidFinancialDataException(dataException);
return dataList;

The “only” code changes that you would have to make would be to point your Unit Test at the new CloudFinanceDal, which will implement the IFinanceData interface, and do TDD until all of your test pass.  Once done your Module configuration would be updated as follows and you would be done!

container.Register<IFinanceData, CloudFinanceDal>()

TRIAD: View-Model, View and Presenter (MVP-VM)

With MVPVM the presenter is responsible for instantiating the view, view model and to populate the view model as required.   The view observes the view model (via data binding) and provides a graphical user interface which represents the state of the view model, i.e., current values of first name, last name, middle initial, etc.  The presenter is allowed to update the view directly with the rule of thumb being if one line of code can prevent numerous lines of complex XAML – to use one line of code.   The view model is a POCO that represents the state of the data and the view.  It solves problems noted with MVC’s Application Model (aka Presentation Model and MVVM) such as having behavior or UI specific properties pollute the domain objects, i.e., visibility and view background color respectively.

Besides reuse against numerous projects, applications, teams and groups there is also the added complexity of multi-targeted enterprise applications.   When your single code base supports the Silverlight, WPF (Desktop) and Windows Phone environment, as is the case with the Password Manager currently under construction at http://PasswordMgr.CodePlex.com.

MVP-VM in Action

The following is from the above noted Multi-targeted application, it is the SecurityModule and will be used to demonstrate MVPVM in action:

ContainerSecurity

In this fictional scenario we have a reusable Security view composed of  the SecurityMainView, SecurityViewModel and the SecurityPresenter triad.   Since it resides in the Gwn.Infrastructures project it is available to an unknown number of applications, teams and groups; only code in the Gwn.PasswordManager.xxxx project is specific to the Password Manager application.

For the next sprint I’m assigned the task of providing a login specific to the Financial group; they will be required to login with their date of birth as well as their login name.   The designer updated the SecurityMainView and SecurityViewModel the last sprint so that if the IsFinancialGroupMember flag is set on the SecurityViewModel the date control field will appear which is bound to the SecurityViewModel.BirthDate field.

I would create a new module loosely comparable to the one shown in the image above and add a call to the applicable BLL so that I could retrieve the security record based on the current system login (the implementation “could be” a ADSUserSecurityDAL), e.g.,

var securityRecord = container.Resolve<IUserSecurityDAL>().GetCurrentUser();
presenter.ViewModel.isFinancialGroupMember =
securityRecord.IsMemberOf(SecGroups.FinancialGroupMember);

I would then update the SecurityPresenter’s  BLL call with an overloaded validate method, so I don’t break existing code, after updating the BLL and DAL as applicable.

Note:  The SecurityViewModel only had two additional properties added and remains un-bloated for the countless other uses of it with no requirement for regression testing as only the new module uses these new features.

  1. ^ PresentationModel and WPF, by John Gossman
Advertisements
This entry was posted in Uncategorized. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s