I’m trying to use the MVP pattern and I’m running into a design problem. I’m developing an application that will have several UserControls. The UserControls themselves have nothing to do with one another and only represent a subset of the actual model. From what I’ve read, people tend to say you should use one Presenter per View. This seems to make sense, but if I have 30 UserControls, do I really want 30 Presenters? On the flip side, if I have 1 Presenter and 1 View that represent the entire “application” view, then I’ll have bloated View and Presenter interfaces. Then each View would have to implement methods that have nothing to do with it. My question is, is there a better way to handle multiple UserControls, or should I just create 1 Presenter for each View?
You should be doing one presenter per one control because of:
that would allow you to have focused unit tests tackling only that control
increased maintainability due to the fact you won’t need to support gigantic presenter containing union of presentation logic of all controls
that would prevent redundancy in cases of having same control on multiple pages
Increases SRP by having controls focusing on their specific logic while the page performs container specific roles:
There are two problems usually mentioned related to the decision “presenter per control”:
Shared context is problem where due to the fact that all of the controls are just showing different pieces of the same page data context, that situation may look like a problematic use case leading to a lot of data retrieval redundant code in every of the controls.
That is easily solvable through dependency injection where page (or controller) performs single data retrieval and then inject the data context object into every of the presenters\views (usually implementing some interface enabling that).
In case of MV-VM pattern (Silverlight, WPF) same effect can be achieved through data bounding where the page would set its DataContext which would then be used from views itself
Communication between views on the same page is second problem which is easily solvable using couple of approaches:
Controls are publishing events to which page subscribes and then makes direct calls to appropriate methods in other controls (page is container to all controls meaning it is aware of all of their members)
Observer design pattern
Event aggregator pattern
In each one of this approaches controls are communicating with each other without being aware of each other
It would make more sense to group the code that is related in one object. So, in this case, if the views are specific groupings of related code, then the presenter would also mimic these groupings. To have a "global" presenter for different views would group unrelated code in one object. It would definitely bloat the interface for the presenter as well. Check out the single responsibility principle.
Now, you could have one Presenter Manager class perhaps that could give you access to each presenter interface, like the Interface Segregation Principle states, by either inheritance (have a global concrete presenter that implements many presenter interfaces..which kind of violates the single responsibilty) or aggregation (having individual presenters for each interface and get functions...thus the global interface would the the get functions) or a combination of both (global presenter being somewhat of an adapter).
I think the best solution though would just to have 30 different presenters.
Each View doesn't have to implement the same interface... Why not define the interfaces for each control, and have one Presenter for the entire screen that contains all the controls? The Presenter can "wire up" the events on each view according to what interface defined events each view requires, to appropriate event handlers on the Presenter (and on a controller if you are doing MVPC). You may also need another interface to represent the Presenter functionality that ALL view need access to in common...
If you're doing MVPC then view events that affect the Model wopuld be "handled" in the Controller, whereas View events that only affect other parts of the View would be handled on the Presenter.
Old question, but I'm going to pipe up and have to disagree with the other answers:
you don't want one presenter per UserControl, any more than you want a unit test on every UserControl - that would be a blind misuse of a design pattern.
A UserControl is not a View.
Each logical area of your application should have one presenter; how each is broken up - how many controls, what shows what - is solely a concern of composition.
Related
I've been using MVVM for a while now with WPF. And i've learnt a lot over the course of development (going from never using it, to having a couple of applications developed in it)
However, recently I had some comments directed at the code which made me wonder if i'm doing things the right way. My current setup works (roughly) like this:
Model - Responsible for storing the data, data validation using
IDataErrorInfo and dirty tracking
ViewModel - Responsible for getting the data (from a repository like
pattern) and formatting it for a view's consumption (things like
filtering, ordering) also responsible for command handling from the
view (save, load, filter changes etc)
View - The usual UI stuff
Now it was mentioned to me that i should NEVER have business logic inside the model, and that the model should be as thin as possible, the viewmodel should be responsible for handling things such as data validation and dirty tracking.
I've seen comments and criticism on both sides of this, with people against and for putting logic in the model, What i have yet to see is any actual reasons for these sweeping statements. So id love to know if there is an actual reason i should be refactoring my setup.
Also, given that i do move the logic to the viewmodel, I can see the need for having multiple viewmodels where i currently have a single, for example:
Person - Model
PersonViewModel - Handles the dirty tracking, data validation etc
PersonsViewModel - Handles getting a collection of PersonViewModels,
filtering etc
PersonsView - The UI
This seems a little redundant, but perhaps i'm misunderstanding something. What I'm really looking for is some actual reasons for doing this one way or another, or if this is another argument like the use of code-behind in MVVM (pure opinion with little reasons etc)
High level description of MVVM:
View: User Interface
Model: Business logic and data (e.g Domain Model+Repositories, or Transaction Script+POCO entities, etc)
ViewModel: Data exposted to view in such form, that is easily consumable from view. Wikipedia's definition says: The view model is an abstraction of the view that exposes public properties and commands.
I like the Practical MVVM Manifesto (archived version) principes: Simplicity, Blendability, Designability, Testability.
This is very high level and abstract description and that's why you may find a lot of variations of MVVM. Whatever mvvm style you choose, keep in mind the responsibilities and principles and you should be ok. Try to avoid complexity. MVVM is not a silverbullet and you cannot cover all scenarios with single design pattern. One mvvm implementation may be suitable for one application but not for another. I, for example, build my mvvm architecture from scratch for each new project to ensure the best fit
When is comes to responsibilities:
Take validation as an example:
validation logic that password and repeat password inputs should be equal is clearly presentation logic and should be present in viewmodel. On the other side, there may be business rule, that password must contain at least one special character. This logic should reside in Model, however you may expose it in viewmodel to be easily consumable from view. It's a business logic, but you may need to present it somehow.
if you have application that only uses webservice to retrieve and store then your model will be probably just the data access components.
Here is couple of resources:
Wikipedia: https://en.wikipedia.org/wiki/Model_View_ViewModel.
MVVM is variation of Martin Fowler's MVP pattern, you may find it useful as well: http://martinfowler.com/eaaDev/PresentationModel.html
MSDN (Pattern and practices): https://msdn.microsoft.com/en-us/library/hh848246.aspx
I like to think of the Model layer as anything that has nothing to do with how the app is hosted (i.e. independent of WPF). It is one or more dlls that represent the business domain and the operations that need to be performed in it. If it would make sense to take theses same dlls and use them in a web application, windows service e.t.c then it is usually a sign that the split between Model and ViewModel is appropriate.
There's no simple answer to your question. The simplest answer is that the model and view model should contain the code that you should unit test. The separation between model and view model is a little less distinct. I like to keep the model as simple as possible and limit it to whatever is exchanged with the server tier. The view model should encapsulate the model, and provide any addition functionality (both business logic and abstract presentation logic) so that you can keep the presentation layer as simple as possible (declarative, in the case of WPF XAML).
I see it this way:
Model - Object that can be passed around. A Common type between different layers for communication.
ViewModel - Specifically created for Views. This should contain UI logic, for example, Data Annotations etc will go here. You might also call your web service methods here (assuming your actual business logic sits in a facade layer, or your database logic sits in a different layer/project) to populate the Views, dropdowns etc. You might end up with multiples of these per view, depending on your design.
View - UI Only.
I am not afraid to put external calls in the ViewModel
I have a little app with a overview of some items (entries). The title of the entry at the list in the overview is a property of the entry.
When I click an entry a kind of tab should open where I can edit the entry. When I edit and save the entry, the overview tab should update the next time.
Here a mockup for better understanding.
App is based on MVVM pattern. Each View has a ViewModel as DataContext. Each ViewModel uses a Model and each Model has a Database.
The overview tab have it's own View, ViewModel and Model (pair). Also the tabs. Each tab for entries use the same pair (singleton instance). Only a few bindings are updated If a other tab is selected.
My question is how to communicate between the tabs.
I have two approaches
Mediator Pattern (Bootstrapper combines two ViewModels with a mediator)
Each Model uses the same Database (Models listen to Database, ViewModel listen to Model)
But I dont' feel well with these approaches.
Should I communicate between Models or between ViewModels? Or is this the wrong way?
UPDATE
I really appreciate all of your answers. In my opinion none of them are wrong or right. I think it's a matter of taste which solution is right for one is. I really like the EventAggregator pattern. Here is a nice video from Karl Shifflett about the implementation of the EventAggregator pattern in PRISM. But it also explains the pattern itself.
#Thomas In my opinion it is a bad solution to do this in one ViewModel. ViewModels have to be separated. MVVM based on Separation of Concerns.
Mediator is a step in a right direction but an Event Aggregator is much more flexible. You can find dozen of implementations. For example, Prism has a ready-to-use implementation.
Communication is between ViewModels. ViewModels register themselves for notifications in the Aggregator and raise notifications on the Aggregator.
You should communicate between ViewModels, if the functionality is related to formatting Model data for display. If your are communicating data from one Model to another, then communicate between Models.
Here is a concrete example: The Microsoft.Practices.Prism namespace, which you can access with NuGet right in Visual Studio, includes a class called CompositePresentationEvent<T>, along with an EventAggregator class which does the actual communicating.
Someplace common to your entire application (I chose App.xaml.vb, but it can be any publicly scoped code file, and it works as well for C# as for VB), you define events by inheriting from that class, and supplying the type T which corresponds to the data you're sending. For example, if you want to send a message that contains a simple string, then declare:
Public Class MyEvent: Inherits CompositePresentationEvent(Of String) : End Class
In your Application class, you define an event aggregator:
Public Shared ReadOnly AppEventAggregator As IEventAggregator = New EventAggregator()
Those two items together give you the means to trade events between any two objects in your application.
This gives your entire application access to an event called MyEvent. Wherever you want to send the MyEvent message, you call its shared Publish(String) method:
Application.AppEventAggregator.GetEvent(Of MyEvent).Publish("This is my event message")
Then, to receive the event, you implement a private read-only field in the class where the event should land, something like:
Private ReadOnly MyEventToken As SubscriptionToken =
Application.AppEventAggregator.GetEvent(Of MyEvent).Subscribe(Sub(eventMessage) DoSomethingWithTheString(EventMessage))
...where DoSomethingWithTheString(eventMessage As String) would be where you process your event.
There's (a lot) more to Prism, of course, but never a need to use more of it than you need, and, as others have pointed out, lots of other MVVM frameworks with similar approaches to solving the same problem.
For me, it's usually a bad sign when I have to program for communication between view models. Sometimes, you have to make communication between view and view model, but the need for connecting two view models seems to always result in combining two view models if possible.
With your mockup, I felt the same bad feeling. Why do you have to have separate view models for tabs in first place? In your case, views can be separate but I don't see any benefit from separating view models. Thus, combining the two view models into one is my recommendation.
Maybe this Post is interesting for you, it Describe a Pattern for a Communication on Type basis. It allows you to Communicate between everything you want, without dependences between them
I understand the general reason why the Model-View-Presenter pattern is a good pattern. It separates the concern so that the same parts of code that deal with presenting information to the user do not worry about calculations, etc. My quesion is why do we need a view that essentially does nothing? All the view does is tell the presenter to do work and get the result back from the presenter. For example, in my C# views, I often just have a bunch of event handlers that call delegates that are implemented in the presenter. Why not just combine the view and the presenter? No concern is really separated because the view does not have any concern.
Two important advantages
We can write multiple views or replace views easily (for example WinForms => WPF implementation)
We increase the testability by creating test views for unit tests
Your View should simply be a way to get data to and from the user. Anything else that is not specifically related to that functionality should be pushed down into the Presenter (or model if it needs be). The presenter handles what the view gets but it should never be concerned with what view does once it gets it.
The presenter is an attempt to look at your "UI" in a more semantic manner. You may have 2 textboxes on your View but your Presenter sees Name and Surname. The idea should be that with the minimal amount of fuse you could lift the View off an pop another one on.
I don't know how much I agree with that and tend to prefer MVVM where you don't have Presenters, instead you have ViewModels which I feel are a better way to define the above abstraction.
I have a main window, which has four user controls on it. These five entities need to communicate with each other. Is there an established method for passing values and objects between UserControls?
Edit: I'm familiar with MVVM, but I am asking for solutions outside of that paradigm.
There are a lot of ways and it depends on what you actual scenario is. The most straight forward one would be to expose public properties and/or events in your UserControls. This is the preferred way if you want to get view specific data across. If your the communication is more model related you should go the route through your ViewModel (and use MVVM).
Generally I think UserControls accessing each other directly is a strong hint toward desgin smell. It is very likely that there is a better aproach for you concrete scenario (Mediator, Eventaggregator, Controller or just the parent control).
You can communicate five entities using making delegates.
I think you need to decide upon domain model according to your project requirement and then create classes which represent entities in your model. Then pass objects of this entities as required.
There are many ways, one is to use events. There are no "direct" methods, you need to route your values through a form or a model class.
There is an established pattern called MVVM (just google for it) that has a unified way of communicating between different contols, databases, web services, calculations etc. MVVM is not a pattern for communicating between different controls, it is a much larger pattern, but it solves that part too.
I'm been experimenting with the oft-mentioned MVVM pattern and I've been having a hard time defining clear boundaries in some cases. In my application, I have a dialog that allows me to create a Connection to a Controller. There is a ViewModel class for the dialog, which is simple enough. However, the dialog also hosts an additional control (chosen by a ContentTemplateSelector), which varies depending on the particular type of Controller that's being connected. This control has its own ViewModel.
The issue I'm encountering is that, when I close the dialog by pressing OK, I need to actually create the requested connection, which requires information captured in the inner Controller-specific ViewModel class. It's tempting to simply have all of the Controller-specific ViewModel classes implement a common interface that constructs the connection, but should the inner ViewModel really be in charge of this construction?
My general question is: are there are any generally-accepted design patterns for how ViewModels should interact with eachother, particularly when a 'parent' VM needs help from a 'child' VM in order to know what to do?
EDIT:
I did come up with a design that's a bit cleaner than I was originally thinking, but I'm still not sure if it's the 'right' way to do this. I have some back-end services that allow a ContentTemplateSelector to look at a Controller instance and pseudo-magically find a control to display for the connection builder. What was bugging me about this is that my top-level ViewModel would have to look at the DataContext for the generated control and cast it to an appropriate interface, which seems like a bad idea (why should the View's DataContext have anything to do with creating the connection?)
I wound up with something like this (simplifying):
public interface IController
{
IControllerConnectionBuilder CreateConnectionBuilder();
}
public interface IControllerConnectionBuilder
{
ControllerConnection BuildConnection();
}
I have my inner ViewModel class implement IControllerConnectionBuilder and the Controller returns the inner ViewModel. The top-level ViewModel then visualizes this IControllerConnectionBuilder (via the pseudo-magical mechanism). It still bothers me a little that it's my inner ViewModel performing the building, but at least now my top-level ViewModel doesn't have to know about the dirty details (it doesn't even know or care that the visualized control is using a ViewModel).
I welcome additional thoughts if there are ways to clean this up further. It's still not clear to me how much responsibility it's 'okay' for the ViewModel to have.
An option which works well for interaction between viewmodels is to bind directly to observer classes sitting between the viewmodel classes.
I think you want to make your top-level ViewModel aware of the existence of the NestedViewModel, it makes sense from a hierarchical standpoint, the master view contains the child view.
In my opinion, your instinct is right, it doesn't feel correct for the nested ViewModel to expose behaviours which are initiated by user actions on the top-level. Instead, the top-level ViewModel should be providing behaviors for the view it is associated with.
But I'd consider moving responsibility for connection construction into an ICommand, and exposing this command via your top-level ViewModel. The OK button on your master dialog you would then bind to this command, and the command would just delegate to the top-level ViewModel, for example, call ViewModel.CreateConnection() when it is executed.
The responsibility of your nested control is then purely collecting and exposing the data to its NestedViewModel, for consumption by the containing ViewModel, and it is theoretically more re-usable in different contexts that require the same information to be entered (if any) - let's say you wanted to re-use it for editing already-created connections.
The only wrinkle would be if the different types of NestedViewModel expose a radically different set of data.
For example, one exposes HostName and Port as properties, and another exposes UserName and Password.
In which case you may need to do some infrastructural work to have your top-level ViewModel.CreateConnection() still work in a clean manner. Although if you have a small amount of nested control types, it may not be worth the effort, and a simple NestedViewModel type-check and cast may suffice.
Does this sound viable?
I recently experimented with Unity (Microsoft Enterprise library) to use dependency injection. That might be a route to go when using interfaces that completely define what both viewmodels need to no from each other. MEF would be another option for dependency injection I'm aware of.
HTH