问题
I am confused. Maybe you can help me :)
I have been following the guidance of CAG and found the MVP pattern very natural to me. Suppose I have a UI-ready Model (for example : implements INotifyPropertyChanged), I use the presenter to bind this Model to a view (presenter knows an interface of the view), keeping my Code-Behind as small as possible handling only Bindings (Model and Commands) properties (or methods) or events for controls that don't have ICommand and in this case immediately being delegated to the presenter.
After a while I've discovered the MVVM pattern, and so far it eludes me. As far as I can tell in my approach I would use MVVM only when my Model is not UI-ready. But would it be more reasonable to keep the presenter and just use a new Model, I fail to understand what do I lose with this kind of usage. I know I am missing something, but what is it :).
Also when your View is generic and can handle many kinds of Models (such as in a PropertyGrid). ViewModel is recommended to be used with a DataTemplate, but in this case you just can't create a Template for each entity in your Model, it is just need to be investigated in runtime, what would you recommend?
While watching Josh Smith talking about MVVM in a screencast, I got a feeling that the re exposing of the Model in the ViewModel is violating DRY (do not repeat yourself), is it really unavoidable? it surprises me nobody his arguing about it in comparison for the flames ADO.Net Dynamic Data metadata classes are getting nowadays.
Hope it was clear enough
Thanks
Ariel
回答1:
Regarding #3, a lot of people will use the "another layer of indirection" argument, saying that changes in the model won't affect the view. While this is technically correct, it's not the real reason to do something like this.
If you consider the Model as the entities you get back from, say, a data access layer or a service (which is what these are generally considered) you begin to see why you need a ViewModel. A ViewModel is designed to extend the model with behaviors the View needs.
For example. If you want to be able to change a property and have the View notified of this change through binding, the property needs to raise some form of NotifyPropertyChanged so that the view can react. This is behavior that your typical model won't have.
In another example, let's say you have a collection and you'd like to flag each item in the collection with a boolean value when a user clicks a checkmark next to that item in the view. You'd need an "IsSelected" property, probably. This is a behavior that the Model shouldn't have to provide.
However I see where you are coming from... I definitely had a problem with this at first. The first time I copy and pasted the contents of a model into my viewmodel, my stomach turned, but you just have to make peace with the fact that for your View to work, it's going to need this extra bit of behavior that a Model shouldn't provide.
No matter how un-DRY this is, forcing your WCF types or LINQ to SQL types (or whatever your favorite ORM is) to implement INotifyProperyChanged is worse.
回答2:
Besides the comments above. I would like to share some of my personal understanding on the difference.
Normally in MVP you have an interface of View, eg. IView, to abstract actual views and bind data to those actual views. In MVVM, instead, you normally use the DataContext of an actual view, eg. a XAML user control, to do databinding, which is similar to the IView in MVP. So let's say, inaccurately, the binding is similar on both patterns.
The major difference is on the Presenter vs ViewModel part. A view model is very different to a presenter which is a bridge for exchanging data between UI and model. It is actually, as what its name means, a model of the view. The data exposed in a ViewModel is mainly for UI process. So from my understanding, in MVVM, the ViewModel is an abstraction of views. In contrary to it, MVP mainly uses IView to abstract views. So normally there are few layers in MVVM than MVP and hence you can write less code to do the same job in MVVM:
MVVM: Model - ViewModel(represents actual views, ie. UI) - Actual Views
MVP: Model - Presenter(a bridge for exchanging data between model and UI) - IView(represents actual views, ie. UI) - Actual Views
The MVVM's advantage over MVP is mostly based on the following 2 great features in Microsoft products,
Commanding in WPF. It could be avilable in Silverlight in the future although there are already some implementations which are not in the Silverlight runtime
DataContext in WPF and Silverlight.
回答3:
Ad.3. It may seem that you repeat yourself by exposing Model in ViewModel, but what you really do is abstracting the Model, so that View knows only about this abstraction (View knows only about ViewModel).
This is because changes to Model shouldn't break the View. Also, your Model can be implemented as many different services that get data from different sources. In this case you wouldn't like View to know about all of them, so you create another abstraction - ViewModel.
回答4:
If the presenter knows the interface of the view, you either need all views used by a presenter to have the same interface or make a presenter for each view. With MVVM the view is aware of the viewModel, and the viewModel is aware of the model (but not vise versa). This means that multiple views can use a VM and multiple VMs can use a Model.
I'm not quite sure what you're asking in your 2nd point. The VM is not the View (or aware of the Views) and to me a DataTemplate defines how an object is displayed. I put my DataTemplates in a ResourceDictionary which definitely belongs in the View. The only bits of WPF 'stuff' in my VM layer are Commands.
I need a little more information to answer your 3rd point. Perhaps it'll answer itself if you dig a little deeper into MVVM.
Here's a related post of mine which might help you
Good luck.
来源:https://stackoverflow.com/questions/839118/composite-guidance-for-wpf-mvvm-vs-mvp