Typically, the user interface in a client application or Rich Internet Application (RIA) contains controls that display application domain data and allows users to modify and submit changes to the data. Defining application logic to control this process in the control's code-behind makes them complex and difficult to understand, maintain, evolve, test, and re-use.
Any of the following conditions justifies using the solution described in this pattern:
- You want to maximize the code that can be tested with automation. (The user interface is hard to test automatically.)
- You want to share code between pieces of the user interface (UI) that require the same underlying behavior.
- You want to separate business logic from UI logic to make the code easier to understand and maintain.
- You want to allow a user interface designer to easily create or modify the UI for your application; by doing this, developers can focus on the application's logic and structure.
- The data that you want to display supports data binding and does not need substantial conversion or adaptation before it can be displayed in the UI.
- The data that you want to display can safely be updated by the UI through data binding.
Separate the responsibilities for the visual display of the user interface and the coordination between the user interface and the domain data to be displayed into different classes named, respectively, the view and the presenter. The view class manages the user interface controls and encapsulates any visual state or behavior that is specific to the UI. The view is data bound directly to a model that provides access to the application's domain data. The presenter class encapsulates presentation behavior and state to manage the interaction between the view and the model by coordinating updates to the model as a result of user interaction with the UI and then it updates the UI as a result of changes in the model. Figure 1 provides a logical view of the Supervising Presenter pattern.
The view is data bound to the model and acts as an observer of it. The view class also forwards user events to the presenter class, so it must maintain a reference to the presenter. Conversely, the presenter must maintain a reference to the view so that it can update the view when the underlying model changes. To facilitate unit testing, the presenter's reference to the view should be through an interface instead of to a concrete implementation of the view. By doing this, you can easily replace the real view with a mock implementation to run unit tests.
To facilitate the Supervising Presenter pattern, the model must be designed to support data binding. By correctly designing the model, developers can leverage the powerful data-binding capabilities provided by Windows Presentation Foundation (WPF) and Silverlight. With data binding, controls that are bound to the model automatically reflect changes when the underlying data changes its value. Similarly, data binding can automatically update the underlying model when the user modifies it in the user interface, such as if the user edits the value in a TextBox element, the underlying data value is automatically updated to reflect that change.
To support data binding, the model should implement the INotifyPropertyChanged interface. Any objects provided to the view through properties should similarly support the INotifyPropertyChanged or INotifyCollectionChanged interfaces. Implementing these interfaces allows the data binding mechanism to monitor the model for changes so that it can automatically update the UI. The model is typically set as the data context for the view so that the binding expressions defined in the view resolve to the corresponding properties on the model.
|For more information about data binding in WPF, see Data Binding on MSDN. For data binding in Silverlight, see Data Binding on MSDN.|
Coordinating View and Model Interaction
When the model is updated, the view has to be updated to reflect the changes. Similarly, when the user interacts with the user interface in the view, the model has to be updated accordingly. With the Supervising Presenter pattern, there are several ways in which each of these can occur.
In this pattern, the view directly interacts with the model through data binding that can be declaratively defined. In this case, changes to the model may be automatically reflected in the UI without presenter intervention. In other cases, the presenter may be required to interpret changes in the model to be able to update the view in more complex ways. Examples include changing the color of a control or dynamically hiding/showing controls according to some complex presentation logic.
When the user interacts with the view, the model has to be updated. The model is data bound to the view, so changes in the data may be automatically made as the user interacts with the user interface without presenter intervention. In other cases, the presenter may update the model on behalf of the view. This is typically the case when the presenter implements commands that can be initiated through the user interface by the user, such as by clicking a button or menu item, or presentation logic that coordinates more complex updates to the model.
To see an example implementation of the Supervising Presenter pattern, see the files EmployeesListPresenter.cs in the View Injection QuickStart.
The Supervising Presenter pattern has the following liabilities
- There are more solution elements to manage.
- You need a way to create and connect views and presenters.
- The model is not aware of the presenter. Therefore, if the model is changed by a component other than the presenter, the presenter must be notified. Typically, notification is implemented with the Observer pattern. For more information about the Observer pattern, see Exploring the Observer Design Pattern.
The following pattern is related to the Separated Presentation pattern:
- Presentation Model. This pattern provides a façade over the model that coordinates all the view's interaction with it. This pattern is suitable for situations where the model cannot be data bound directly to the view.
For more information about the Supervising Presenter pattern, see the following:
For more information about software design patterns applied in the Composite Application Library and Stock Trader Reference Implementation, see Patterns in the Composite Application Library.