Transferred from: http://www.cnblogs.com/sunshine-anycall/p/4153357.html
This article is translated from: http://www.objc.io/issue-13/mvvm.html. In order to facilitate the reader and save time, some are not related to the topic of the article is removed. If the reader wants to see the original text, it can be accessed directly from the previous URL. The author has also done iOS for many years, from university until now n years. For the development of a B-grid app is very pursuit. Learn a lot of things, such as the silver bullet and so on, design patterns or something. However, in the face of the rapid expansion of the code, even Caigaobadou seems to be at a loss. So he began to think about life ...
Mvc? There is another explanation: Massive view controller, translated by a lot of view controller meaning. There are times when there is such a feeling that there are too many View controllers. Especially when a person is working overtime to fix a bug at night, it feels more obvious. So you'll be tempted to pull it all over again!
From an architectural standpoint, perhaps a derived architecture of MVC is more appropriate for MVVM. There is no discussion of MVVM's past life. Everyone in the garden. NET talent has been playing this thing on WPF a long time ago. Take a look at what iOS MVC looks like, and then step into MVVM. MVC for iOS:
This is a typical MVC architecture. Models represents the data, the views represent the time user interface, the view controllers in the middle coordinates. When you think about it, you will find that although the view and view controllers are two completely different things, they are tightly coupled. When a view can be used in conjunction with a different view controller, or a view controller can be used in conjunction with a different view. So, this architecture is actually like this:
This gives an accurate description of how the code under the MVC architecture is written. However, this does not reflect a significant increase in the view controller in iOS development. In a typical MVC application, a lot of logic processing is placed in the view controller. Some of them really need to be in the view controller. But there is also a large part of the "Show logic" presentation. This is an MVVM term that refers to the process of converting the data in Model D into a form that can be displayed in a view. For example, converting a nsdata into a certain form of nsstring is a process.
The above figure is missing part of the content. What is missing is that part of "presentation logic". This part can be called "view model" after it is abstracted. This section is between view, view controller, and model.
It seems more reasonable to put. This drawing accurately describes what is MVVM, an enhanced version of MVC. Here, we can formally connect the view with the controller. And move the display logic out of the view Controller to form a new object: View model. MVVM sounds complicated, but it's an MVC that wears a new shirt. is essentially the same as MVC.
Now you should be aware of what MVVM is. So, why use this thing? Because writing code with this architecture can reduce the complexity of the view controller , and the logic presented is easier to test. Here's a code to show the two benefits of MVVM.
3.1 are set out in the text to emphasize:
- MVVM is compatible with your existing MVC architecture.
- MVVM makes your app easier to test.
- MVVM can coexist well with a stereotyped schema.
As mentioned earlier, MVVM is an enhanced version of MVC. So it's easy to see how this pattern coexists with the previous MVC architecture. Let's start by creating a simple person model and a corresponding view controller.
Import uikitclass Person { var salutation:string? var firstname:string? var lastname:string? var birthdate:nsdate? Init (salutation:string, firstname:string, lastname:string?, Birthdate:nsdate?) { self.salutation = salutation self.firstname = firstName self.lastname = lastName self.birthdate = BirthDate }}
Now suppose we have a view controller called Personviewcontroller, and in viewdidload we use model person to set some label values:
Override Func Viewdidload () { super.viewdidload () if self.model.salutation!. Utf16count > 0 { self.nameLabel.text = "\ (self.model.salutation) \ (self.model.firstName) \ (self.model.lastName ) " } else{ self.nameLabel.text =" \ (self.model.firstName) \ (self.model.lastName) " } var Dateformatter = NSDateFormatter () Dateformatter.dateformat = "Eeee MMMM d, yyyy" self.birthDateLabel.text = Dateformatter.stringfromdate (self.model.birthdate!) }
These are the most common formulations of MVC code. Here's a look at how to write the view model.
Import Uikitclass Personviewmodel { var person:person! var nametext:string? var birthdatetext:string? Init (Person:person) { Self.person = person if Self.person?. Salutation?. Utf16count > 0{ self.nametext = "\ (self.person.salutation) \ (self.person.firstName) \ (self.person.lastName)" } else{ self.nametext = "\ (self.person.firstName) \ (self.person.lastName)" } var dateformatter = NSDateFormatter () Dateformatter.dateformat = "Eeee MMMM d, yyyy" self.birthdatetext = Dateformatter.stringfromdate (self.person.birthdate!) }}
In this way, the display logic has been migrated out of the Viewdidload method. Now the Viewdidload method seems to be a lot lighter.
Override Func Viewdidload () { super.viewdidload () self.nameLabel.text = Self.viewModel.nameText Self.birthDateLabel.text = Self.viewModel.birthDateText }
You'll see that there's no need to make any big changes to the MVC architecture. Almost just the original code moves slightly. Fully compatible with MVC, it reduces the weight of the view controller and makes it easier to test.
Let's talk about testing. The hard-to-Test view controller is literally a name. In MVVM, a large portion of the code is moved to the view model. And the view model is easy to test. Such as:
var person:person! Override Func SetUp () {super.setup () var salutation = "Dr." var firstName = "First" var lastn Ame = "Last" var birthDate = nsdate (timeintervalsince1970:0) Self.person = person (salutation:salutation, F Irstname:firstname, Lastname:lastname, Birthdate:birthdate)} func testusersalutation () {var ViewModel = P Ersonviewmodel (Person:self.person) xctassert (viewmodel.nametext! = = "Dr First", "Use salutation available \ (viewmodel.nametext!) ")} Func testnosalutation () {var Localperson = person (salutation:nil, FirstName: "First", LastName: "Last", BirthDate: NSDate (timeintervalsince1970:0)) var ViewModel = Personviewmodel (Person:localperson) Xctassert (ViewModel. nametext! = = "First Last", "should not use salutation \ (viewmodel.nametext!)") } func Testbirthdateformat () {var ViewModel = Personviewmodel (Person:self.person) Xctassert (viewMode L.birthdatetext! = = "Thursday January 1, 1970", "Date \ (viewmodel.birthdatetext!)") }
If you didn't move the code into the view model, you had to initialize a view controller and, of course, a bunch of view in the View controller. Then compare the values of some properties of these view (when the label is mentioned in the previous example). This is not only very inconvenient, not direct, but also to form a very vulnerable test: because, the view controller's attempt level simply can not have any changes, once the change test will fail! Or the test is compiled at all, but. The benefits of using MVVM for testing are obvious. In the example above, the logic is relatively simple. This easy-to-test benefit is even more noticeable if you change the complex display logic of other product environments.
Note that the examples used above are relatively simple. There are no properties that need to be modified. You can initialize an object directly with an initial value. For the model that has been modified. We need to use a binding mechanism. This will ensure that the value of the view model based on the model is changed after some value of the model has been modified. Further, after the model value has been modified, the value of the view model of the view call can be modified accordingly. That is, a change to the model, and the model-related view model and the value of the view can be updated synchronously.
On OSX, you can use the cocoa bindings. But there's no such luxury on iOS. But Key-value observation is perfectly capable. It only increases the amount of code in many properties. You can also use Reactivecocoa. Of course it's just a choice. A nice binding framework that will make MVVM Paula:.
We've talked a lot about MVVM. MVVM is spoken from an easy-to-test perspective. A good binding framework makes MVVM more useful. If you want to learn more about MVVM, you can look here. These articles tell more about the benefits of MVVM. Or this article, which describes the use of MVVM on the original project and has achieved good results. And here's an open-source app, entirely based on MVVM, that readers can refer to.
[Fall in love with Swift] 14th bullet: Introducing MVVM in iOS projects