Download the Code Sample
Of all the successful projectsI’ve been a part of, the most successful ones shared a common result: As the application grew larger, the codebase became smaller. On the surface, this may seem contradictory, but coding in an Agile environment lends itself to a shrinking codebase. As requirements change, refactoring occurs, and this refactoring opportunity—coupled with hindsight—provides the ability to reuse existing components more efficiently while eliminating duplicate code in the process.
In contrast, there have been some monolithic projects, which were sometimes deemed successful, where the source code grew and grew with little opportunity for reuse. These projects became resource-intensive and a risk to future growth. What was the fundamental difference? The infrastructural design pattern used. The patterns you use will determine whether you paint yourself into a corner or keep your back to the open opportunities the future might bring.
In this article, I’ll present one such pattern—overlooked by many Windows Presentation Foundation (WPF) developers because of the popularity of the Model-View-ViewModel (MVVM) pattern—called the Model-View-Presenter-ViewModel (MVPVM) pattern. This enterprise application design pattern was introduced in the Microsoft patterns & practices Prism project (Prism.CodePlex.com). (Note: This pattern was unnamed, so I refer to it as MVPVM.) Prism is best described with an excerpt from its Web site overview:
“Prism provides guidance designed to help you more easily design and build rich, flexible, and easy-to-maintain Windows Presentation Foundation (WPF) desktop applications, Silverlight Rich Internet Applications (RIAs), and Windows Phone 7 applications. Using design patterns that embody important architectural design principles, such as separation of concerns and loose coupling, Prism helps you to design and build applications using loosely coupled components that can evolve independently but that can be easily and seamlessly integrated into the overall application. These types of applications are known as composite applications.”
The popularity and success of MVVM overshadows MVPVM even though MVPVM is the evolution of MVVM (as this article will demonstrate). MVPVM provides all of the power and capability of MVVM while introducing the scalability and extensibility of the Model-View-Presenter (MVP) pattern. If your understanding is that MVVM has evolved from MVP for WPF, then you’ll find this article enlightening.
Before we can fully appreciate the power and benefits of MVPVM, we have to understand how this pattern evolved—we have to understand our history. The Model-View-Controller (MVC) pattern is a crucial component to achieving this understanding, so I’ll first introduce MVC, perhaps in a way you’ve never seen before.
Please note that this MVC discussion is within the context of desktop applications; Web applications are another story and beyond the scope of this article.
In Martin Fowler’s “GUI Architectures” document (bit.ly/11OH7Y), he states the following about MVC: “Different people reading about MVC in different places take different ideas from it and describe these as ‘MVC.’ If this doesn’t cause enough confusion, you then get the effect of misunderstandings of MVC that develop through a system of Chinese whispers.” The “Whatsa Controller Anyway” document at bit.ly/7ajVeS sums up his point nicely stating: “Computer scientists in general have an annoying tendency to overload terms. That is to say, they tend to assign more than one meaning (sometimes contradictory) to the same word.”
Smalltalk MVC gets further complicated by the fact that developers lack a common core of experience with their great architects in regard to the architect environment. As such, the overloading of terms and “Chinese whispers” are convoluted even more by the fact that most of us don’t even know what a Controller is because we’ve never had to use one—the OS has always handled its functionality for us. With a few facts to provide the common core of experience we lack, you’ll find MVC is actually easy to understand, and that the “C” in MVC has nothing in common with the “P” in MVP.
The Controller does have a concrete origin (which is well worth understanding but doesn’t necessarily match modern approaches to MVC in the context of current technologies). The founding father of MVC, Trygve Reenskaug, wrote about that in 1979 in his document on “Models-Views-Controllers” (bit.ly/2cdqiu). This document begins to provide some insight on the purpose of the Controller. Reenskaug wrote:
“A controller is the link between a user and the system. It provides the user with input by arranging for relevant views to present themselves in appropriate places on the screen. It provides means for user output by presenting the user with menus or other means of giving commands and data. The controller receives such user output, translates it into the appropriate messages and passes these messages on to one or more of the views.
A controller should never supplement the views, it should for example never connect the views of nodes by drawing arrows between them.
Conversely, a view should never know about user input, such as mouse operations and keystrokes. It should always be possible to write a method in a controller that sends messages to views, which exactly reproduce any sequence of user commands.”
This concept is illustrated in Figure 1.
A “message,” in the context of MVC object-oriented programming (OOP), is a means of executing methods. They were described as “messages” because back then, virtual calls were a new concept and it was a way of distinguishing them from static function calls. In Chapter 1.2 of the book “Smalltalk, an Introduction to Application Development Using VisualWorks” (Prentice Hall, 1995), by Trevor Hopkins and Bernard Horan, the authors note “… if the receiving object understands the message it has been sent, then one of its internal operations (or methods) will be performed. This, in turn, may cause some computation to take place (by acting on one or more of the object’s internal variables).” (Note: This “message-sending” OOP concept is available in Prism via its EventAggregator.)
The book nicely outlines the responsibilities of Smalltalk MVC in Chapter 29, “Introduction to Models, Views and Controllers,” by teaching us that Controllers derive from the Controller class. It states, “Instances of this class have a reference to a sensor representing the mouse and keyboard, so that it can process input.” It continues to tell us that the two distinct actions initiated from a Controller are communications with the Model (see Figure 1) and communications with the View without affecting the Model.
Figure 1 Controller Receives Input and Sends Message (Method to Execute); Views Can’t Catch User Input
In Smalltalk MVC, “every” View will have a Controller and only one Controller at any given time can be active. In the original Smalltalk MVC, the UI was polled; the top-level ControlManager class asks each of the Controllers of the active View if it wants control. Only the View that contains the cursor can accept control. If a View is read-only, there’s a NoController class available that’s designed to refuse control. A View with subviews has the responsibility to poll the Controllers of its subviews. Once a Controller has accepted control, it will query the results of the keyboard or mouse and send messages to the View or Model as applicable, such as mouse move, button click and so on. In MVVM terms, this would be comparable to subscribing to a control’s events in either the View’s codebehind or via a ViewModel command. When a user interacts with the control, the applicable method will be called.
By this point, you can start to get a glimpse behind the purpose of the Controller within the context of MVC and an environment that doesn’t automatically handle events for you. Unlike Smalltalk MVC developers, WPF developers don’t have to query keyboard buffers and package and raise events. You merely subscribe to them and the applicable method “automagically” receives them via the Microsoft Event Pattern. With this knowledge, the following will perhaps have a different, and less confusing, meaning.
In Steve Burbeck’s article, “Applications Programming in Smalltalk-80: How to Use Model-View-Controller (MVC)” (bit.ly/3ZfFCX), he states the following:
“The controller interprets the mouse and keyboard inputs from the user, commanding the model and/or the view to change as appropriate. Finally, the model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller).”
See Figure 2 for an illustration of this concept.
Figure 2 Smalltalk Model-View-Controller
A final point to bring clarity to what could be a muddy topic is in the document, “Twisting the Triad, the Evolution of the Dolphin Smalltalk MVP Application Framework,” by Andy Bower and Blair McGlashan at bit.ly/o8tDTQ (PDF download). This is one of the more comprehensive documents I’ve read on the topic. The authors note the following about the Controller: “The views, of course, are responsible for displaying the domain data while the controllers handle the raw user gestures that will eventually perform actions on this data.”
I bring this final point up so that I have an opportunity to provide another definition. To fully comprehend the article (and others on MVC), you have to understand what “gestures” means (see Figure 1). In my research, I came across the article, “An Introduction to GUI Programming with UIL and Motif” (bit.ly/pkzmgc), which states the following:
“The essence of these steps is that a Motif program does nothing until the user requests some action. The actions are requested by selecting a menu item, by clicking a button or other window, or by pressing a key. These, collectively, are user gestures. Each gesture will trigger an application function to carry out some tasks.”
Andy Bower, coauthor of “Twisting the Triad,” shared his thoughts on “gestures” with me:
“My take on ‘gestures’ is that they’re a coalescence of one or more user events into something more meaningful.
For example a TextController might absorb key down and key up events and convert them into individual ‘keypress’ gestures. Similarly, a SelectionInListController (the Controller attached to a list box) might absorb several mouse-down, mouse-tracking and mouse-up events within a list and treat them as a single list ‘selection’ gesture.
Looked at like this, we see that a modern event-driven OS already does most of this gesture processing for us.”
To summarize Controller logic, you can see that the Controller function is rather consistent among the variations of MVC referenced. Because Microsoft controls (widgets) handle “the mouse and keyboard inputs from the user,” you merely subscribe to the events and point to the method that needs to be executed—the “Controller” within your smart controls executes the method for you (handled at the OS level). As such, you don’t have a need for a Controller, as clearly indicated by the “Twisting the Triad” article. Without the Controller, you’re left with the Model-View pattern for Windows applications. You have to bear this in mind as you study MVC and its application and presentation models because without the Controller, there is no Triad (see Figure 3).
Figure 3 Without the Controller, It Has Been Model-View (not Model-View-Controller)
It’s worth mentioning that it was not only the Controller that caused ambiguity with MVC. With Smalltalk MVC, the business/domain logic is in the Model, and with VisualWorks MVC the ApplicationModel contains the “application” logic required to present one or more business/domain objects to the user (see Figure 4). The “Twisting the Triad” article covers this in more detail. If you consider that the Application Model and Presentation Model have the same functionality, with the distinct difference being that the Presentation Model “cannot” access the View (Martin Fowler made a clear distinction so as not to overload terms), then WPF developers can quickly grasp Presentation Model because it’s in essence MVVM. John Gossman, founding father of MVVM, explains this in his “PresentationModel and WPF” blog entry at bit.ly/pFs6cV. Like Martin Fowler, he was careful not to overload terms. This effectively gives us a clear understanding of what MVVM is; it’s a “WPF-specific version of the PresentationModel pattern.”
Figure 4 VisualWorks Model-View-Controller
Once you can see MVC in its true light, it helps you understand the true roles of the Model and View. These are in essence the only two locations for business/domain logic. After reading “Twisting the Triad,” you can see it was the responsibilities of the Application Model that were moved to the Presenter and that you can’t simply replace the Controller with a Presenter—it wouldn’t make sense, because they aren’t synonymous.
It’s beyond the scope of this article to go into MVP with the attention it deserves; fortunately, there are numerous documents that address it, such as “Twisting the Triad” and the “Potel Paper,” which you can download at bit.ly/dF4gNn (PDF).
I will, however, note that the “Twisting the Triad” article states an important point that I alluded to, which led to the evolution of MVC to MVP:
“Another irritating feature of MVC, at least with respect to Dolphin, was that the idea of a controller did not fit neatly into the Windows environment. Microsoft Windows, like most modern graphical operating systems, provides a set of native widgets from which user interfaces can be constructed. These ‘windows’ already include most of the controller functionality embodied as part of the underlying operating system control.”
I’d also like to highlight from Martin Fowler’s “GUI Architectures” article his statement that “This need to manipulate the widgets directly was seen by many as a bit of dirty workaround and helped develop the Model-View-Presenter approach.” This is important to understand because MVVM has ingrained the Presentation Model mentality into many WPF developers; they believe it’s “bad programming” to update the View directly. This is true for MVVM and the Presentation Model because once you reference the View, you can no longer reuse the ViewModel with a different View (the main reason for this rule). This limiting factor was one of the reasons Smalltalk MVC evolved to the MVP pattern. With MVPVM, developers can access the View and ViewModel directly (it’s tightly coupled), which permits the View and ViewModel to remain completely decoupled (see Figure 5). Views can reuse different ViewModels and ViewModels can be reused by different Views (as you’ll see later when I discuss the MVPVM pattern); this is one of the many great benefits of MVPVM.
Figure 5 Model-View-Presenter, Supervising Controller
Andy Bower shared the following information on the topic with me to provide further clarification:
“It’s perhaps worth pointing out that the aim of all of these patterns is reuse via plugability. Keeping the coupling loose wherever possible and the interfaces as small as possible gives maximum reuse in the way the components can be recombined.
However, note that the Model has effectively two interfaces that must be compatible with any associated View and Presenter. The first is the standard function call interface, used for getting/setting values and performing commands. The second is the event interface, which must be the same as that expected by the View (observer pattern). This combination of interfaces can be referred to as a ‘protocol.’
For example, in Dolphin MVP, a list widget (triad) needs three components with compatible protocols. A ListModel, a ListView and a ListPresenter.”
Once you understand why you don’t want to update a View directly—and realize that this reason contributed to a new design pattern that would permit you to effectively reuse objects by eliminating the constraint of not being able to update the View—then you have the option to embrace the new opportunities that evolution offers. You live in an Agile world and—like your code—you have to change your thought patterns “lest history repeats itself.”
I was taught this pattern early in Prism’s lifecycle, specifically in Drop 7 of the CompositeWPF. Lost in all of the mystical powers of Prism, I recognized the MVP pattern, which helped me find some footing. I quickly learned (as I teach new developers) to simply go to the Presenter and you’ll have your starting point for figuring out the code and application. How code execution gets there can be learned later and doesn’t have to interfere with critical timelines; the impact of the difficult learning curves can be managed.
The following definitions of the MVPVM components have excerpts from “Twisting the Triad” as applicable; I found this information to be informative, comprehensive and accurate, so in the interest of presenting to you the best information possible, I’ll merely quote this article’s definitions. These definitions hold true today for MVPVM (see Figure 6) as they did for MVP back in March 2000 when “Twisting the Triad” was written.
Figure 6 Model-View-Presenter-ViewModel
(Note: Prism is the context of this article, however, MVPVM will work without Prism; the various components will simply be tightly coupled to their implementation versus being resolved—loosely coupled by the Unity or Managed Extensibility Framework [MEF] dependency injection container.)
“This is the data upon which the user interface will operate. It is typically a domain object and the intention is that such objects should have no knowledge of the user interface.” —“Twisting the Triad”
The separation of the Model from the ViewModel is required to address the concerns of dependency injection and its use within the Business Logic Layer (BLL) and Data Access Layer (DAL) to Create, Read, Update, Delete and List (CRUDL) persisted data. In MVPVM, only the DAL has access to the persisted Model objects.
“The behavior of a view in MVP is much the same as in MVC. It is the view’s responsibility to display the contents of a model. The model is expected to trigger appropriate change notifications whenever its data is modified and these allow the view to ‘hang off’ the model following the standard Observer pattern. In the same way as MVC does, this allows multiple views to be connected to a single model.” —“Twisting the Triad”
(Note: I used the preceding quote to emphasize that MVP isn’t a new pattern and that it’s as valid today as it was when MVP evolved from MVC. However, the quote does reference the “Model,” whereas MVPVM uses the “ViewModel.”)
With MVPVM, there’s never a need to have code in codebehind. The Presenter has access to the View and can subscribe to events, manipulate controls and manipulate the UI as required. This proved beneficial while developing the multi-targeted application that accompanies this article. The User ListBox wouldn’t respect the data binding for the selection changed event, so I had to develop a way that would work for all three platforms (because they share the same code). When the View is activated, I call the WireUpUserListBox (see Figure 7, line 174) and use the View to obtain a reference to my lstUserList control (which resides in a DataTemplate). Once it’s found, I wire up to the SelectionChanged event and update the ViewModel SelectedUser property. This works on the desktop, Silverlight and Windows Phone.
Figure 7 Benefits of Being Able to Access the View Directly
A View has no knowledge of the ViewModel, so they aren’t tightly coupled. As long as a ViewModel supports all of the properties to which a View binds, it can easily use the View. The Presenter is responsible for wiring up Views to their ViewModels by setting their DataContext to the applicable ViewModel.
“While it is the view’s responsibility to display model data, it is the presenter that governs how the model can be manipulated and changed by the user interface. This is where the heart of an application's behavior resides. In many ways, an MVP presenter is equivalent to the application model in MVC; most of the code dealing with how a user interface works is built into a presenter class. The main difference is that a presenter is directly linked to its associated view so that the two can closely collaborate in their roles of supplying the user interface for a particular model.” —“Twisting the Triad”
The Presenter will have dependencies on the interfaces for the BLLs from which it needs to retrieve domain objects (data), as shown in the left pane of Figure 8. It will use the resolved instances as configured in the module (see Figure 8, bottom right pane) or bootstrapper to access the data and populate the ViewModel.
Figure 8 Security Module Code
Typically, only the Presenter will be tightly coupled in MVPVM components. It will be tightly coupled to the View, ViewModel and the BLL interfaces. Presenters aren’t intended to be reused; they address specific concerns as well as the business logic/rules for those concerns. In cases where a Presenter can be reused across enterprise applications, it’s likely a module would be better suited for the task—that is, you could create a login module (project) that could be reused by all of your enterprise applications. If you code against an interface, the module can be easily reused using dependency injection technologies such as the MEF or Unity.
“In MVP, the model is purely a domain object and there is no expectation of (or link to) the user interface at all.” —“Twisting the Triad”
This prevents the ViewModel from being tightly coupled to a single View, permitting it to be reused by numerous Views. Likewise, the ViewModel will have no application business logic, so ViewModels can be easily shared across enterprise applications. This promotes reuse and application integration. For example, look at Figure 8, top right pane, line 28. This SecurityCommandViewModel resides in the Gwn.Library.MvpVm.xxxx project (where xxxx = Silverlight, desktop or Windows Phone). Because a User ViewModel will be required in most applications, this is a reusable component. I have to be careful not to pollute it with business logic specific to the demo application. This isn’t a problem with MVPVM, because the business logic will be handled by the Presenter, not within the ViewModel (see Figure 6).
(Note: As the ViewModel properties are populated by the Presenter, they’ll raise NotifyPropertyChanged events, which will alert the View that it has new data—it’s the View’s responsibility to update itself to the ViewModel data upon notification.)
BLLs have no knowledge of the persisted Model data. They work strictly with domain objects and interfaces. Typically, you’ll use dependency injection to resolve your DAL interface within the BLL, so you can later swap out the DAL without affecting any downstream code. Notice in Figure 9, line 34, that I’m using a MockBll implementation for IBusinessLogicLayer for my demo application. Later I can easily replace it with a production implementation of the interface with one line of code because I’ve developed against an interface.
Figure 9 Registering BLL, DAL and Commands
Business logic isn’t limited to the BLLs. In Figure 9, I register named types (for IPresenterCommand) so that I can use dependency injection as a factory. When the user clicks on a button (lines 29–33 in Figure 10), the command parameter is resolved (instantiated) by the baseclass and the applicable command is executed. For example, the LoginCommand (Figure 8, top right pane) is a command that will activate the UserManagerView. All that was required to wire this up was a Button command in XAML and an entry in the SecurityModule (see Figure 8, bottom right pane, line 32).
Figure 10 DataTemplate for the UserCommandViewModel
Persisted domain data could be stored in SQL databases or XML or text files, or retrieved from a REST service. With MVPVM, only the DAL holds specific information required to retrieve data. The DAL will only return domain objects to the BLL. This averts the need for the BLL to have knowledge of connection strings, file handles, REST services and so on. This enhances scalability and extensibility; you can easily switch your DAL from an XML file to a cloud service without affecting any existing code outside of the DAL and the application configuration file. As long as your new DAL unit tests work for the CRUDL processes, you can configure the application to use the new DAL without impacting current applications and their usage.
Thanks to the patterns & practices team, I’ve been able to achieve success for my clients using bleeding-edge technologies and patterns such as MVPVM, without failure. I found that by keeping up with the team’s pace, technologies and patterns, that as newer technologies and patterns emerge, I can pull from past experience to help me more easily find my way in new territory.
MVP is a constant and consistent pattern that I’ve seen used since the earliest days of my architectural studies using patterns & practices projects. To fully appreciate MVP, you have to understand your history, particularly the components of MVC. This isn’t easy, because of the numerous factors discussed.
But by understanding our past, and the reason for our evolution, we can more quickly grasp the need for and power of newer patterns. Even with Prism and all of its complexity and magic, you’ll be able to bypass a difficult learning curve by simply knowing this history and appreciating the need for the newer patterns. In all of the successful projects I’ve been involved with since the emergence of this pattern in early drops of Prism, MVPVM has revealed no issues, speed bumps or brick walls (through evolution they appear to have been eliminated), permitting developers to increase velocity as we build applications that are scalable, extensible and stable.
Bill Kratochvil, an independent contractor, is a lead technologist and architect for an elite team of developers working on a confidential project for a leading company in the medical industry. His own company, Global Webnet LLC, is based in Amarillo, Texas.
Thanks to the following technical experts for reviewing this article: Andy Bower, Christina Helton and Steve Sanderson
More MSDN Magazine Blog entries >
Browse All MSDN Magazines
Subscribe to MSDN Flash newsletter
Receive the MSDN Flash e-mail newsletter every other week, with news and information personalized to your interests and areas of focus.