Using MVP and MVVM patterns in Android development is not new. Various MVP/MVVM related articles and open source libraries are common, even dazzling. So why should I paint on this blackboard that has been covered with graffiti? Do I want to show my presence? Of course! No no no... not entirely! I also want to warn everyone who reads this article: your understanding of MVX may not be completely correct! Note: In this article I will use MVX as a general term for MVC, MVP, and MVVM. We all know that the evolution of MVX is from Rolling Ball to MVC, then from MVC to MVP, and then from MVP to MVVM. Then, according to the conventional routine, I should introduce what MVC, MVP, and MVVM are, and introduce the respective responsibilities of M, V, C/P/VM.
My purpose is to correct some misunderstandings about MVX, so the premise is that you have to have some understanding of MVX. In order to prevent people from taking detours when using MVX, I decided to summarize and correct some misunderstandings about MVX that I saw. After my analysis, the reason for these misunderstandings is actually: not really understanding the core values of MVXism! In fact, the core idea of MVX is also very simple. Don't get me wrong, it is not about prosperity, democracy, etc., but about separating the presentation layer from the business layer. Separation of presentation layer and business layer Separation of presentation layer and business layer is called Separated Presentation by Matin Fowler. The presentation layer is VX and the business layer is M. If someone sees this and finds that it is different from what you think MVX is, then your understanding of MVX is likely to be wrong, and in serious cases, you may have taken the revisionist route! From the perspective of separation of presentation layer and business layer, M, V, and X are not equal identities, but M and VX. From the beginning to the end, M's responsibilities have not changed, but VX has changed. With the development of software development technology, the continuous change of interaction forms or interaction media, the logic of the presentation layer has become more and more complex. The evolution of MVX is a process of constantly exploring and handling the complex logic of the presentation layer. Of course, the evolution from one form to another is not necessarily to solve more complex interaction logic, but it may also be a "more elegant" way to handle the presentation layer logic. Now that we have the concept of separation between the presentation layer and the business layer, the first misconception is easy to explain. Mistake 1: Presenter or ViewModel is responsible for handling business logic This is a very common misconception, and many articles introducing MVP or MVVM have said this. As mentioned earlier, business logic belongs to the M layer, so what does Presenter or ViewModel do? Do they handle presentation logic? Yes, or most presentation logic is handled in Presenter or ViewModel. Previously, I called these logics above the business layer view logic, but now I will call it presentation logic for the sake of consistency (it feels weird to add the word "吧"). Here I will briefly explain what presentation logic is and how View and Presenter/ViewModel work together. Suppose your application has a profile page for personal information. This page has two states, one is browsing state and the other is editing state. The state transition is triggered by an edit button. In the editing state, some information items can be edited. Then there is an obvious presentation logic here, which is to click the button to switch between browsing/editing state. The current popular form (or variant) of MVP is called Passive View. Like MVVM, it now tends to hand over almost all presentation layer logic to Presenter or ViewModel. The View layer needs to do very little, basically receiving user events and then passing them to Presenter or ViewModel. To explain using the profile page example above, the View layer is responsible for receiving the click event of the edit button, and then notifying the Presenter/ViewModel, and then the Presenter/ViewModel notifies the View whether to display the browsing state view or the editing state view. The sample code of MVP is roughly like this:
Note: This sample code is only for showing the presentation layer logic, it does not involve the Model layer and will not compile! Do you understand what I mean? The Presenter/ViewModel decides what to display based on the current interaction status, and the View is responsible for how to display it. For example, in the pull-down refresh scenario, the View tells the Presenter/ViewModel that it has received the pull-down event, and then the Presenter/ViewModel tells the View to display the refresh prompt view. As for what the refresh prompt looks like, it is up to the View to decide. Of course, the Presenter/ViewModel may also determine that the current network is unavailable, and let the View display a prompt view indicating that the network is unavailable. Why should Presenter/ViewModel handle almost all presentation logic? The main purpose is to improve testability and include as much presentation logic as possible in the scope of unit testing. Because it is too difficult to unit test the display of view controls, View is basically impossible to unit test, but Presenter/ViewModel can be unit tested:
You see, all these presentation logic can be unit tested! Do you understand what I mean?
OK, now you know the presentation layer, but what is the business layer used for? Now we are going to talk about M. What is M? M refers to those who like to get sex from being abused... Oops, sorry, I got it mixed up! Oh ~ being knowledgeable is a problem! M stands for Model, and a longer one is Domain Model, which is called Domain Model in Chinese. Let's take a look at the definition of Domain model on Wikipedia:
How about it, is it easy to understand? Of course not! I just started to understand that the Model layer is to handle business logic, and now there is another MMM...Domain, I don’t know where to think! Domain, simply understand it as business, I think there is nothing wrong with it. I quote this sentence here mainly to emphasize that the Model layer contains business data and operations on business data (behaviour and data), and also to introduce the second wrong view. Error 2: Model is static business data When we develop business modules, we often define some data structure classes. For example, a personal profile may correspond to a UserProfile class, and an order data may correspond to an Order class. These classes do not have any logic, but only some simple getter and setter methods. Some people think that data structure classes like UserProfile or Order are Models. We have already emphasized that the Model layer contains business data and operations on business data. Instances of data structure classes such as UserProfile or Order cannot even be called objects. You can read Uncle Bob's article Classes vs. Data Structures. Objects have behaviors. A data structure instance has no behavior and is not even an object. How can it represent the Model layer? Static business data cannot represent the Model layer. Business data and operations on business data together constitute the Model layer, which is the business logic. Let's take another example. Suppose you are making an app called "Jutie". This app now has only one page to display a list of recommended blogs. OK, how should we write it in the form of MVP? Let's ignore the View that has no interaction with the Model layer. In addition to processing the presentation layer logic, the Presenter layer also issues business instructions to the Model layer. Note that the Presenter does not process business logic, and the real business logic is still completed by the Model layer. The sample code is roughly as follows:
What? There is only one line of code in your BlogModelImpl, and you tell me it is business logic? Everyone calm down, put down the bricks, machetes, and maces in your hands. Although the logic in the BlogModelImpl class is simple, it is indeed business logic. It is precisely because the business logic is relatively simple that the BlogModelImpl class is very concise. Let's look at it from the perspective of Presenter and see why loadRecommendBlogs() belongs to business logic. The concept of blog is undoubtedly a business concept. According to the previous explanation, it can be judged that "getting a list of recommended blogs" does not belong to the presentation layer logic. Therefore, the implementation of this logic is not what the Presenter needs to care about. It should be the responsibility of the Model layer. Since it is the Model layer, it should be business logic; furthermore, since blog is a business concept, then Blog is the data structure of business data. LoadRecommendBlogs() involves operations such as the creation and assembly of business data Blog, so it should also be business logic. Seeing this, some people may have some misunderstandings: the so-called business logic processing is the data acquisition logic such as network requests and database queries, that is, the Model layer is responsible for data acquisition. This is the third wrong view I want to talk about. Wait, let me write a title first ⬇ Error 3: The Model layer is responsible for data acquisition To put it bluntly, those who have this misunderstanding still do not understand the business logic. Of course, business logic itself is a very abstract concept, difficult to understand and difficult to distinguish. I dare not explain it in detail, because if I say too much, I am afraid that you will find that I am actually swimming naked. The business logic layer is not responsible for data acquisition. The data acquisition responsibility lies in the lower layer of the Model layer. This is why I wrote the implementation logic of BlogModel so simply, because the responsibility for data acquisition is all handed over to the BlogFeedRepository class, and the Model layer only handles business logic. BlogFeedRepository is a repository class for blog lists. BlogModel uses the fetch() method of BlogFeedRepository to obtain a list of blogs tagged as recommend, that is, a list of recommended blogs. BlogModel does not care how BlogFeedRepository obtains the corresponding blog data. It can be obtained through a network request or from a local database. Any changes in the data source should not affect the business logic in BlogModel. Since the business logic in BlogModel is so simple, why do we need to add such a Model layer instead of letting Presenter directly use the BlogFeedRepository class to obtain data? Of course there is a reason! Suppose the "Jutie" app we just introduced, with only one blog list page, still attracts a lot of users to use it. The product manager decides to try to explore monetization methods at this time. The first is to add advertising data to the blog recommendation list. Suppose again that because the advertising data and blog data belong to different back-end teams, the data on both sides have not yet been integrated, and the client is temporarily responsible for adding the advertising data to the blog list. At this time, BlogModel finally highlights the necessity of its existence. The presentation layer is not responsible for the acquisition and integration of advertising data, and BlogFeedRepository is not responsible for the acquisition and integration of advertising data. The integration of advertising data is business logic, which is the responsibility of BlogModel, and the acquisition of advertising data is the responsibility of a dedicated data warehouse class. The sample code is as follows:
Considering that ads and blogs may have different integration strategies, different implementations can be replaced as needed, so the integration strategy is encapsulated in the BlogAdComposeStrategy interface. The integration strategy is also part of the business logic, but since the implementation details of the integration strategy do not need to be paid attention to here, I think it is okay not to write it out, anyway, I wrote it. What I want to say here is that getting advertisement data and integrating it into the blog list is also part of the business logic. If the Model layer is omitted, the advertisement integration logic will be placed in the Presenter or Repository layer, which is definitely inappropriate. Placing business logic in the wrong layer will inevitably cause subsequent maintainability and scalability problems. Error 4: Model layer depends on Presenter/ViewModel layer Some people do not understand the dependency relationship between the Model layer and the upper layer, and write the dependency relationship as bidirectional, which is wrong. The business layer should not depend on the presentation layer, but vice versa. In fact, the Presenter/ViewModel depends on the Model layer through interfaces, and the Model layer does not depend on the Presenter/ViewModel at all. Just like in my previous sample code, the Model layer will not have any words like presenter. The upper layer monitors the data changes of the Model layer through the observer mode (LoadCallback interface is also a kind of observer mode), and the Model layer does not need to care whether the upper layer is the Presenter or the ViewModel. at last After reading this, I wonder if you have a deeper understanding of MVX? Do you have a clearer understanding of presentation layer logic and business logic? In fact, there is more to discuss about MVX. For example, some people think that the Model layer is not the place where business logic is actually processed. It is just an upper encapsulation layer of the business module. I think this makes sense. In a complex business module, the business is hierarchical, and the Model layer in MVX is the top layer of all business layers. There is also a data layer under the business layer I just mentioned. This is a typical three-tier architecture concept, namely the presentation layer, business layer and data layer. The logic is layered, so the architecture must also be layered. MVX can be used as the beginning of our exploration from code to business and even to architecture. |
<<: WeChat Pay crashed on a large scale! Official response: The problem still exists
>>: Google has worked hard for three years to finally make Android phones upgrade faster
Do you still remember Xiaohongshu, the cross-bord...
The fresh food e-commerce industry continues to r...
Source: Dr. Curious Original title: Teach you how...
In growth work, AB testing can be said to be a me...
In live broadcast, the script can be based on the...
Merchants can freely set the functions and usage ...
[[153327]] When I was young, I screwed up. The si...
In addition to providing customers with the conte...
When you think of viruses, what comes to your min...
On December 22, Tesla CEO Elon Musk revealed on T...
Humans are always very complicated. They believe ...
The matter began with a platform turnover statist...
In the process of operating the community, we all...
By Rich Heimann The "brain in a jar" is...
Cockroaches, commonly known as "xiaoqiang&qu...