Preface This article is written to answer a friend's question about the MVC/MVP/MVVM architecture. It aims to introduce the design ideas of the three architectures of MVC/MVP/MVVM under iOS as well as their respective advantages and disadvantages. MVC
MVC first existed in desktop programs. M refers to business data, V refers to user interface, and C is the controller. In specific business scenarios, C is the connection between M and V, responsible for obtaining input business data, and then outputting the processed data to the interface for corresponding display. In addition, when the data is updated, C also needs to submit the corresponding update to the interface for display in a timely manner. In the above process, because M and V are completely isolated, when switching business scenarios, usually only the corresponding C needs to be replaced, and the existing M and V can be reused to quickly build a new business scenario. MVC has greatly improved development efficiency due to its reusability, and has now been widely used in various terminal development. Now that we have gone through the concepts, let's take a look at how MVC/MVP/MVVM behaves in specific business scenarios.
I believe that many of you have created the page (business scenario) in the figure above or similar pages. The specific implementation methods of each programmer may be different. Here are some of the programmers' writing methods that I have seen:
The programmer quickly finished writing the code, pressed Command+R, and ran it. There was no problem, so he went to do other things with satisfaction. Later one day, the product required that this business be modified. When the user viewed other people's information, the page in the above picture was displayed. When viewing their own information, there was an additional draft box display, like this: So Xiaobai changed the code to this:
Later, the product developer thought it would be nice to have a recycle bin for users to view their own pages, so the programmer added a piece of code logic, and then... As requirements change, UserVC becomes more and more bloated, more and more difficult to maintain, and has poor scalability and testability. Programmers also find that there seems to be some problems with the code, but where exactly is the problem? Isn't this MVC? We use a diagram to represent the above process: From this picture, we can see that the user information page, as a business scene Scene, needs to display multiple data M (Blog/Draft/UserInfo), so there are multiple Views (blogTableView/draftTableView/image...), but there is no connection layer C between each MV. The logic that should have been distributed to each C layer is all packaged and thrown into the Scene for processing, that is, MCV becomes MM...-Scene-...VV, and the C layer disappears inexplicably. In addition, the two cells of V are directly coupled to M (blog/draft), which means that the inputs of the two Vs are tied to the corresponding M, and reuse is out of the question. ***, the test for this business scenario is extremely troublesome, because the business initialization and destruction are bound to the life cycle of VC, and the corresponding logic is also related to the click event of View. The test can only be done by Command+R, click click click...
Maybe the class name of UIViewController confuses newcomers, making them think that VC must be the C layer in MVC, or maybe Views like Button and Label are too simple and do not need a C layer to cooperate with them. In short, I have seen too many such "MVC" in the projects I have worked on. So, what is the correct way to use MVC? Still taking the above business scenario as an example, the correct MVC should look like this: As a business scenario, UserVC needs to display three types of data, corresponding to which there are three MVCs. These three MVCs are responsible for data acquisition, data processing and data display of their respective modules. What UserVC needs to do is to configure these three MVCs and notify their respective C layers to acquire data at the right time. After each C layer gets the data, it will process it accordingly and render it to its own View after processing. UserVC*** will lay out the rendered Views. The specific code is as follows:
The Blog module consists of BlogTableViewHelper (C), BlogTableView (V), and Blogs (C). There is something special here. Blogs does not contain M, but CellHelper, the C layer of Cell. This is because the MVC of Blog is actually composed of multiple smaller MVCs. There is nothing much to say about M and V. Let's mainly talk about what TableVIewHelper, which is C, does. In actual development, the View of each module may be newly created and laid out in the Storyboard corresponding to the Scene. In this case, each module does not need to create its own View (such as BlogTableViewHelper here), and the Scene can be passed to the C layer for management. Of course, if you use pure code, the View needs to be created by the corresponding module itself (such as UserInfoViewController below). This depends on your own wishes and is harmless. BlogTableViewHelper provides external interfaces for obtaining data and necessary construction methods, and performs corresponding initialization based on its own situation. When the fetchData interface is called externally, Helper will start the data acquisition logic. Because some page displays (such as HUD) may be involved before and after data acquisition, and the specific display is directly related to the Scene (some Scenes display HUD, some may display another style or not display at all), so this part will be handled by the Scene itself in the form of CompletionHandler. Inside Helper, if data acquisition fails, the corresponding error page will be displayed. If data acquisition succeeds, a smaller MVC part will be created and notified to display data (that is, to notify CellHelper to drive Cell). In addition, the pull-up refresh and pull-down load logic of TableView also belongs to the Blog module, so it is also handled in Helper. In the page jump logic, the page to jump to is directly configured by the Scene through VCGeneratorBlock, so it is also decoupled (you can also pass data to the Scene layer through methods such as didSelectRowHandler, and let the Scene do the jump, which is the same). ***, V(Cell) now only exposes the Set method for external settings, so it is isolated from M(Blog), and there is no problem with reuse. This series of processes are self-managed. In the future, if the Blog module will be displayed in another SceneX, SceneX only needs to create a new BlogTableViewHelper and then call helper.fetchData. The logic of DraftTableViewHelper and BlogTableViewHelper is similar, so I won’t post them here. I will simply post the logic of the UserInfo module:
UserInfoViewController has more addUI subcontrol layout methods than the two TableViewHelpers, but the rest of the logic is similar. It is also a self-managed MVC and can be used in any Scene after only initialization. Now that the three self-management modules have been built, UserVC only needs to assemble them according to its own situation, just like building blocks. As a business scene, Scene (UserVC) does very simple things. It configures (configuration), lays out (addUI) the three modules according to its own situation, and then notifies each module to start (fetchData). Because the display and interaction of each module are self-managed, Scene only needs to be responsible for the parts that are strongly related to its own business. In addition, we create a UserVC subclass SelfVC for self-access, which does similar things. That’s about it for MVC. Compared with the wrong MVC method above, let’s see what problems are solved: 1. Code reuse: The V (cell/userInfoView) of the three small modules only exposes the Set method to the outside, and is isolated from M and even C, so there is no problem with reuse. The MVC of the three large modules can also be used to quickly build similar business scenarios (the reuse of large modules is worse than that of small modules, which I will explain below). 2. Code bloat: Because most of the logic and layout of the Scene have been transferred to the corresponding MVC, we only assembled MVC to build two different business scenes. Each business scene can display the corresponding data normally and has corresponding logical interactions. To complete these things, it only takes about 100 lines of code with spaces (of course, I ignored the layout code of the Scene here). 3. Easy to expand: Whether the product wants to add a recycling bin or a defense tower in the future, all I need to do is create a corresponding MVC module and add it to the corresponding Scene. 4. Maintainability: The responsibilities of each module are separated. If there is an error, it can be fixed there without affecting other modules. In addition, the code of each module is not much. Even if the code writer leaves one day, the person who takes over can quickly locate the error module according to the error prompt. 5. Testability: Unfortunately, the initialization of the business is still bound to the life cycle of the Scene, and some logic still needs to be triggered by UI click events. We can still only press Command+R, click click...
As you can see, even the standard MVC architecture is not perfect, and there are still some problems that are difficult to solve. So what are the shortcomings of MVC? The summary is as follows: 1. Excessive emphasis on isolation: In fact, the MV(x) series all have this shortcoming. In order to achieve complete isolation of the V layer, V only exposes Set methods to the outside world. Generally, there is no problem, but when there are many properties that need to be set, it is still very tiring to write a large number of repeated Set methods. 2. Strong coupling between business logic and business display: As you can see, some business logic (page jump/like/share...) is directly scattered in the V layer, which means that when we test these logics, we must first generate the corresponding V before we can test. Obviously, this is unreasonable. Because the business logic ultimately changes the data M, our focus should be on M, not the V that displays M. |
>>: Custom View-Imitate the reward button of the Hupu live broadcast game interface
In our daily life, you must have felt static elec...
Justill Poster Color Lab Training Camp 2.0 Resour...
(Pictures from the Internet) In fact, it is not j...
Conversion is the key factor in paid promotion . ...
Why is "white-collar women aged 18-35" ...
In the past few months, we have participated in t...
There are many cases of people becoming famous ov...
With the global release of iPhone 7 and iPhone 7 ...
introduction [[319525]] Google's GMS? Check o...
[[141348]] Mobile game design concepts typically ...
Mixed Knowledge Specially designed to cure confus...
How to continue to gain traffic for Xiaohongshu N...
gossip Some people say that the air conditioner c...
Now the adults are at work and the kids are doing...
Xue Xun's "Strategic Pivot for Great Bra...