Using "vanilla" WPF (no MVVM framework like Prism).
Let me say up front that I absolutely advocate coding against abstractions/interfaces vs. implementations whenever possible.
In WPF, when you do your bindings in the view, you are really not coding your bindings against the viewmodel interface. You are really binding against an implementation of the viewmodel/datacontext. I think you co开发者_JS百科uld even argue that you are binding against a blank canvas, since the view doesn't really have any knowledge of what it will bind to at runtime.
So is a view model interface that includes every property that the view will bind to a useless abstraction? Should view model interfaces be leaner, only containing methods needed to change state (or handle commands, etc.).
I hope that question makes sense. :)
IMHO, the ViewModel is a Model for the View. 90% of the time, they will likely be 1 to 1... the useful part is moving the logic back into something more testable than XAML. Together, they compose the UI, but the UI behavior is separated from the UI presentation.
Personally, I do not make use of ViewModel interfaces. Between the Command Pattern and the loose binding that WPF and Silverlight use, I don't feel that abstraction would be useful.
I might use ViewModel interfaces in a system where the behavior and View state differed widely based on some business criteria. E.g. if your View was doing driver's license field editing and the fields required varied from state to state, you could make a case for a single, complex view bound to an IStateDriversLicenseViewModel interface. The correct one could be dependency injected based on the state you are working on and could expose properties like IsOrganDonorSectionVisible, to allow the view to reflect the correct changes. However, in this case I suspect a view composed of user controls would lead to fewer problems and less complexity in maintenance.
Abstraction [ie Interface programming] is useful if and only if loose coupling [ie an implementation-agnostic relactionship between consumer and producer] is desired.
Depending on your interpretation of Model View ViewModel [MVVM], tight coupling is permitted.
In practice, the typical scenario I have seen is a tight coupling between View and ViewModel and between View and Model(s). Typical, because Views are designed to fulfil a specific business requirement, ViewModels are tailored to suit the View to facilitate the View's business role.
As Ben Von Handorf suggests, that part of our application that actually adapts the underlying Model(s) to the ViewModel should be separate from our View [at least the declarative Presentation part]. So the adapting is typically captured by a View's implementation of a Command. So, while the declarative aspect of the View has no knowledge of the underlying Model(s) and is loosely coupled, the business implementation, or View's Command, introduces a tight coupling between View and Model. Again, this is cool because the View's sole purpose is to leverage that data in a specific manner as part of its business.
I too am a fan of abstraction, in particular Interface Programming, Dependency Injection [DI], and Inversion of Control [IoC]. However, when tight coupling makes sense, as it does in MVVM, then abstraction is an over-complication.
IMO, the simplicity introduced by tight coupling is what makes MVVM so attractive over its cousins in the Model View Controller [MVC] space.
I think it's generally not sensible to define an interface when you're only ever going to create one class that implements it. That describes every view model class I've ever created. And the view can't use interfaces anyway.
I do sometimes use interfaces in view model classes, but only if I need to define interactions between those classes that don't properly live in the model.
精彩评论