The Misunderstood MVC

Source: Internet
Author: User

The MVC pattern (model–view–controller) is a software architecture model in software engineering, which divides the software system into three basic parts: model, view and controller.

The MVC pattern, first proposed by Trygve Reenskaug in 1978, is a software architecture invented by Xerox Palo Alto Research Center (Xerox PARC) in the 1980s for programming language Smalltalk. The purpose of the MVC pattern is to implement a dynamic program design that simplifies the subsequent modification and expansion of the program, and makes it possible to reuse a part of the program. In addition, this mode makes the program structure more intuitive by simplifying the complexity. The software system is separated by the basic parts of itself and also gives the functions of the basic parts.

  Now that MVC has become the mainstream client programming framework, in IOS development, the system has implemented common view classes for us: UIView, and Controller classes: Uiviewcontroller. Most of the time we need to inherit these classes to implement our program logic, so we almost evade the design pattern of MVC.
But, decades later, have we really used the design pattern of MVC? Not really, MVC is a layered approach, although it is clear, but if used improperly, it is likely that a lot of code is concentrated in the Controller, so that the MVC pattern into the Massive View Controller mode.

How does a Controller's bloated problem solve?

Many people try to solve the problem of the Controller being bloated under the MVC architecture.
First, let's look at the features of MVC's architecture. In fact, design patterns are often done for the Don ' t repeat yourself principle, which requires reusable code to be reused as much as possible to ensure reuse. In this design pattern of MVC, we find that both View and model conform to this principle.

    1. For the view, if you are well-abstracted, the animation of one app can be easily ported to other apps, and Github has a lot of UI controls that are nicely packaged in the view layer, making it easy to open source for reuse.
    2. For Model, it is actually used to store the data of the business, and if done well, it can be reused easily. For example, when I was in the Youdao Cloud notebook IPad version, we directly and the IOS version of the code to reuse all the Model layer. The Model layer code for IOS and IPad was re-used again when starting a business as an ape-bank client. Of course, because it is related to the data meaning of the business itself, the reuse of the Model layer is mostly within a product and is unlikely to be open-source to the community like the View layer.

After talking about the View and Model, let's think about how many controller,controller can be reused? After we have finished writing a Controller, can we easily reuse it? The conclusion is: very difficult to reuse. In some scenarios, we may be able to reuse controllers in ways like Addsubviewcontroller, but the reuse scenario is very, very few.
If we can realize that the code inside the controller is not reusable, we know what code should be written in the controller, which is the code that cannot be reused. In my opinion, the Controller should only store these reusable code, which includes:

    • When initializing, the corresponding View and Model are constructed.
    • Monitor the events of the model layer and pass the data from the model layer to the View layer.
    • Listens to the event of the view layer and forwards events from the view layer to the Model layer.

If the Controller has only the above code, then its logic will be very simple, and it will be very short.
But it's hard to do that because there's a lot of logic that we don't know where to write, so we're all written in the Controller, and then we'll see where the rest of the logic should be written.

How to thin the body of viewcontroller?

Objc.io is a very well-known IOS development blog, the first lesson in the above "lighter View Controllers" on a lot of such skills, we first summed up its views:

    1. Separate the UITableView Data Source into a different class.
    2. Separate the logic of data acquisition and transformation into another class.
    3. Separates the logic of the assembled control into another class.

Do you have any idea? In fact, MVC is only three layers, but it does not limit you to have only three layers. Therefore, we can extract the Controller's overly bloated logic to form a new reusable module or architecture hierarchy.
My personal abstraction of logic has the following summary:


Abstracting a network request into a separate class
The new handwritten code, directly in the Controller with a afnetworking to send a request, the requested data is passed directly to the View. Get started some of the students, know to move these request code into another static class inside. But I don't think it's enough, so I recommend encapsulating each network request directly into a class.

    • Encapsulating each network request as an object is actually using the Command pattern in design mode, which has the following benefits:
    • Isolate network requests from specific third-party libraries, and easily replace the underlying network libraries later on. In fact our IOS client was originally based on ASIHTTPRequest, and it took us two days to switch to afnetworking easily.
    • It is convenient to handle common logic in the base class, for example, the data version number information of the ape question Bank is processed uniformly in the base class.
    • It is convenient to handle caching logic in the base class, as well as some other common logic.
    • Facilitates the persistence of objects.


Abstracting the interface's assembly into a specialized class
New handwritten code, like in the Controller of a UILabel, Uibutton,uitextfield to Self.view on the Addsubview method put. I suggest that you can split the code from the Controller in two ways.

    1. Construct specialized UIView subclasses to be responsible for the assembly of these controls. This is the most thorough and elegant way, but a little more troublesome is that you need to take over the event callbacks of these controls first and then expose the Controller back to you.
    2. Use a static Util class to help you do UIView assembly work. This approach is slightly less thorough, but relatively simple.

For some UI controls that can be reused, I recommend using method one. If Project engineering is more complex, I also suggest using method one. If the project is too tight and the code for the related project is not too much, you can try method two.

Construction ViewModel
Who says MVC can't use ViewModel? The advantages of MVVM are as good as we can learn. The practice is to Viewcontroller to View the process of passing data, abstracted into the process of constructing ViewModel.
After this abstraction, View only accepts ViewModel, and the Controller only needs to pass ViewModel such a line of code. In addition to the process of constructing ViewModel, we can move to another class.
In practice, I recommend that you specifically create a construction ViewModel factory class, see Factory mode. In addition, data access can be specifically pumped to a Service layer, which provides ViewModel access.


Specifically constructs a storage class
Just said ViewModel's structure can draw to a Service layer. Accordingly, the storage of data should also be done by specialized objects. In the Little Ape Search project, we have a class called useragent, dedicated to handling local data access.
With data access in a dedicated class, you can do extra things for access. Like what:

    • Add cache to some hotspot data
    • Handling data migration-related logic

If you want to do something finer, you can abstract the storage engine another layer. This allows you to easily switch the underlying storage, such as switching from SQLite to Key-value's storage engine.

Summary:

By extracting the code, we can further split the Viewcontroller in the original MVC design pattern, construct the network request layer, ViewModel layer, Service layer, Storage layer and other classes to work with the Controller, so that Cont Roller is simpler and our App is easier to maintain.
In addition, I do not know that we notice that the controller layer is very difficult to test, if we can be able to thin the controller, it is more convenient to write Unit test to test various interface-independent logic. The Mobile Automation test framework is not very mature, but the Controller's code is extracted, is to help us do the testing work.

The Misunderstood MVC

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.