Address: http://developer.51cto.com/art/200907/139086.htm
1. Prerequisites
It can be said that mvvm is a model designed for WPF, or mvvm is just a variant of MVC. However, in practice, if you or your team are not used to binding, it makes little sense to study mvvm.
In addition, I personally think that using command and creating a reasonable and simplified way to use command is equally important as using binding.
2. Birth
To solve problems in the real world, we need to abstract things in the real world, and then get the domain object, no matter the anemia or rich blood, we can all simply attribute them to "models abstracted from the real world", that is, our model, that is, "M" in M-V-VM ".
However, it cannot interact with our users. Therefore, we need to create an interface (view, view) for it. This view can interact with user input devices, which is great, but the question is, how can we associate a view with our model? Binding can be used. For example, the text in a text box in the view is associated with the "user name" in the model, you can access and modify the "user name" of the model by using the text box.
This is extremely simple, but in actual programming, we find that attributes (and methods) in the model are often less easily associated with interface controls in the view, for example, "Type mismatch": the type required by the interface control does not match the type raised by the attribute in the model. "Additional operations required": Data in the model must be processed to be transmitted to the view, and vice versa. at this point, we realized that the view seems to require a "helper" class to handle some extra work.
the Code contained in this helper can be stored in many places except the model (we do not consider arguments such as anemia and blood-rich ). ), for example, in view, remember that you did this when you just learned the form Program development, and put the vast majority of processing logic in the so-called codebehind. later, as you can see in various design patterns books Odel is separated to realize that the view can be replaced (for example, you can say that the software you carefully designed runs on the Form program, web or even mobile), and MVC is available. with MVC, it seems that the debate and variant models such as M-V-XXX, such as MVP and mvvm, and even MVP also have two ways of supervising controller and presentation model. but there are two main problems: first, the relationship between model and view is completely isolated? Unidirectional or bidirectional? Second, what functions does this "XXX" need to complete and simple process scheduling? Complex rule processing? Okay, there is no relationship between these arguments. Whether or not to adopt a certain mode depends on your development environment (such as language features and framework features) and your business features and the main changes you face.
However, unlike MVC and MVP, mvvm is introduced not only for technical reasons, but also for the following reasons: the development method of the software team has changed. if you have been developing a WPF project for a period of time, you may have a clear feeling: how to assign programmers and artists to work on the view layer building. before continuing reading, you can take a look at one of my previous articles.Article"Between UI Designer and developer ". in the past, our team used the "integration model", and I used part-time roles of "integrator. this is not bad. but to be honest, this is just a temporary scheme that has to be done in special circumstances. So we have made a lot of effort to start to switch to the "Harvest mode". We have to switch to this mode, at least two basic conditions are required:
(1) You have an artist who can skillfully use tools such as blend to output XAML to programmers. He focuses on pure UI/UE, and he must also have a certain "programmer" thinking. so that the output can run well as a part of the program, rather than just "looks" like that.
(2) You need a programmer who can break away from the view layer but still write high-quality code.
Fortunately, we are trying to create condition 1 and have achieved good results. (you can recruit an artist who has experience writing Flash scripts and has great enthusiasm for learning, and perform blend training on him ). the mvvm mode provides great convenience for us to implement the second condition. why does the MVC/MVP Mode fail while mvvm does? In MVC and MVP modes, the view layer has a lot of code logic. The view layer is developed by programmers. Although the UI/UE team will do a lot of work, however, the "implementer" on this layer is still a programmer. in the past development, it worked very well, while in WPF development, programmers were not able to display the view layer, although the artist (referring to the artist who met the preceding condition 1) was very good, but he would say, "Unfortunately, I won't program ". therefore, we need a way to extract the code logic of the view layer, and the view layer is pure so that the artist can create it completely. correspondingly, the corresponding logic of the view layer needs to be extracted to a code layer so that programmers can focus on it.
In retrospect, we only need to write some code (C #) behind view (XAML #), it is nothing more than to transfer some data and process the data when the data is transferred or perform some operations when the user interacts with the interface control, the simplest example is that in MVC, when the interface is interactive, view calls a method in controler to pass the corresponding "indication" of the operation to "background. in previous technologies, such "cohesion" code is required. in WPF, you can use another technology to "Connect" between layers. This is "binding" and "command ", and the "attachbehavior" we will mention later ". through binding, we can transmit data; through command, we can call operations. (The Role of attachbehavior will be discussed later ). binding and command can be written in XAML. In this way, the CS files after XAML can be completely discarded or ignored. such a XAML File It is exactly what the artist needs. the code for binding and command definition descriptions and other related information should be put there. Of course, it is not a view, not a model, but a "viewmodel ". viewmodel is customized for this view. It contains binding information, such as converter and datacontext for the view binding, it includes the definition of command so that the view layer can be used directly. In addition, it is also a variant of controler, which must be responsible for the scheduling of business processes.
As a result, this figure was created, and mvvm was born, as the "Fashion Hero" said.
3. viewmodel and unit test
If you are a programmer who is using the mvvm mode to build software, I advise you to forget the view as soon as possible. what you are facing is this pattern "unittest-viewmodel-model" (this is not a pattern, it is just something that I have expressed for the moment to elaborate on my point of view ).
I remember that there was a Model-View-abstractview mode, while the VM in mvvm is actually a abstractview: the actual action of view. it is an abstract view, with the soul of a view, without the corresponding visual controls. therefore, for programmers, creating such an abstract VM can be considered as creating a view layer. after the artist completes the actual view composed of countless controls, we can use the binder such as binding and command to combine the abstract view with the actual view.
So how do we know whether our VMS work normally before the bonding? Unit test!
Before explaining the importance of unit testing for viewmodel, I would like to give you a sentence: "view and unit test are just two different types of viewmodel consumers" (Josh Smith ). if we regard viewmodel as a producer, both view and unit test have the same status as consumers. unittest has a higher consumption capability than view. or you can simply think that view is just a less recommended test method. therefore, to implement this mode, the unit test on viewmodel is necessary, and this test does not depend on any UI control. (isn't the development that does not correspond to viewmodel? Should it be driven by testing? TDD ?)
4, attachbehavior
generally, using the WPF features such as command, binding, and attachproperty, the combination of view and viewmodel works well. suppose we have a button. When the button is clicked, we need to complete some operations. It is very easy to encapsulate the operation into a command and bind it to the button, but what if we want to perform other operations when the button is loaded? Because the button is not directly triggered by the load event, the command cannot be used. you cannot directly write the load event processor in the CS file corresponding to the XAML where the button is located. This is in conflict with the mvvm design. A bad solution is to inherit the button and write a command triggered by load, which is feasible but obviously not good. just as a control does not have a property and uses attachproperty without inheritance, we can use attachbehavior.