MVC, MVP, and MVVM are some of the common patterns to guide programmers toward creating decoupled solutions. Learning about these is not a trivial task, picking the one that is best for a specific problem is a challenge, and implementing it correctly based on the descriptions I found on the internet would be even more challenging. I have gone back and pulled out the earliest references I could find to these patterns for the definitions and explanations, but then put them in a modern context to simplify the explanations. There are a few variations of these patterns in the wild today, and many, many differing interpretations of them.
In a nutshell, MVC is basically this: The user interacts with the view, which will then notify the controller. The controller updates the model. The model notifies the view, which then calls back to the model to get the information needed to display.
Looking at MVP, it is almost the same thing, with the presenter taking on more responsibilities organizing data that can be interacted with in ways specific to an application. The distinction is subtle but important. A presenter will provide access to the data in ways other than how the data is stored. It allows two applications to access the same data store but in ways that are specific to the needs of the application. In contrast, a controller always provides the same access to the data regardless of the specific needs. There are also several variations of MVP: Passive View, Supervising Controller, and Presentation Model just to name a few.
Lastly MVVM; MVVM is also very similar to MVC with the significant difference being databinding. Using databinding, the view is databound in either in a one way or two way binding. In cases where the application needs are too specific to be directly represented in the model, the ViewModel (Model of a View) is used. The ViewModel converts Model types into View types, it has view state information, and provides commands that the View can use to access the Model.
Given these explanations of the patterns regardless of what other descriptions of the patterns you have been told, they all have one common component that makes them what they are. The View interacts with the model. This is only different in the variations of the MVP pattern. Given this information, how do you decide which pattern to use?
If you are using Silverlight or WPF - MVVM is the best option. For the most part, any technology that allows you do declaratively develop your UI MVVM seems like the right choice. MVC seems like the unevolved ancestor to MVP. It is only because VS2010 integrates the pattern into the asp.net project templates that there is any acceptable use for it.
The Supervising Controller variation of MVP is a primitive version of MVVM. If a supervision controller seems like a good option, consider MVVM instead. The Presentation Model variation of MVP pulls the presentation behavior from the view. The Presentation Model can handle simple things such as colors and formatting or you can take it further to handle location of the UI elements and much more. Your viewstate is in the PresentationModel instead of the view which can make testing easier. I personally don’t like this approach because it requires your presentation model to synchronize with the view in ways that will make you dependent on specific implementations of your view.
The passive view variation of MVP is nice in that it does not have the view interacting with the model. It also does not contain the state of the view that it interacts with. The flow is the user interacts with the UI, the UI notifies the presenter, the presenter interacts with the model and then the presenter updates the UI as needed. This approach seems flawed to me in that the presenter requires a UI, real or otherwise to operate.
There is one more variation of MVP: Separated Presentation. It has the strengths of the passive view variation, but the View calls to the presenter but the presenter never calls to the view. In this way the presenter can exist without any View at all, but the View requires a presenter. In the case where the controller is required to the notify the view of changes, the observer pattern is used. This approach seems much more intuitive to me, and it is also remarkably easy to test.
Some quick code:
public interface IView { }
public interface IPresenter
{
event EventHandler
void SomethingImportant();
}
public interface IModel { }
public class Model : IModel { }
public class Presenter : IPresenter
{
public event EventHandler
public Presenter(IModel model)
{ }
}
public class View : IView
{
IPresenter presenter;
public View(IPresenter presenter)
{
this.presenter = presenter;
this.presenter.Notify += new EventHandler
}
private void Button_Client(object sender, EventArgs e)
{
this.presenter.SomethingImportant();
}
private void Presenter_Notify(object sender, EventArgs e)
{
}
}
How much code sits in the View vs Presenter is determined by the needs project. My general approach is any code that would be shared across any UI goes in the presenter. All code specific to the UI implementation codes in the view. The more code that codes into the presenter, the easier time you will have testing the code.
The Conclusion
There are many UI architectures available to programmers and the explanations of how to implement them are varied sometimes misleading, and often contradictory. It is important to use caution when picking the architecture as getting it wrong will result in a lot of work later on. In cases such as WPF and Silverlight MVVM is a clear choice. ASP.Net guides you directly toward MVC. In all other cases I would lean heavily toward the Separated Presentation variation of MVP until specific reasons can be found to go a different way.
Comment
Nice post. The differences between MVC, MVP and MVVM can be very confusing. We use MVVM extensively within the Prism framework on numerous finance projects. It generally takes developers a while before the design patterns in Prism, including MVVM, click.
Great post. I gave MVVM a try for a small WPF project I did this summer, and I didn't find myself liking it too much. Although the databinding was nice, and it made Unit Testing easier, I found myself putting all of the application logic in the ViewModel, which felt wrong to me. Much like your last suggestion, I eventually moved all of the logic out to the Presenter class, and kept the ViewModel as passive as possible.
Sorry for the bad writing this week. This was put together very fast. Feel free to ask for points of clarification where the writing got sloppy.
© 2024 Created by Daniel Leuck. Powered by
You need to be a member of TechHui to add comments!
Join TechHui