📜 ⬆️ ⬇️

Development patterns: MVC vs MVP vs MVVM vs MVI

From the translator: this article is a reworking of the English article on development patterns. In the process of adaptation to Russian, a lot had to be changed. Original




The choice between different development patterns is always accompanied by a series of disputes and discussions, and the different views of the developers on this complicate the task even more. Is there a solution to this ideological problem? Let's talk about MVC, MVP, MVVM and MVI pragmatically. Let's answer the questions: “Why?”, “How to find a consensus?”


Introduction


The question of choosing between MVC, MVP, MVVM and MVI touched me when I was making an app for Warta Mobile with my team. We needed to move from a minimally viable product to a proven and fully equipped application, and we knew that it would be necessary to introduce some kind of architecture.


Many have an unshakable opinion about the various development patterns. But when you consider an architecture, such as MVC, it would seem that completely standard and specific elements: model (Model), view (View) and controller (Controller), different people describe in different ways.


Trygve Reenskaug - invented and defined MVC. 24 years after that, he described it not as an architecture, but as a collection of real models that were based on the idea of ​​MVC.


I came to the conclusion that since each project is unique, there is no perfect architecture.


It is necessary to consider in detail the various ways of implementation, and think about the advantages and disadvantages of each.


What do we want to achieve?


Scalability, maintainability, reliability


Obviously, scalability is the ability to expand the project, implement new functions.


Maintainability — can be defined as the need for small, atomic changes after all functions are implemented. For example, it may be a color change in the user interface. The better the project maintainability, the easier it is for new developers to support the project.


Reliability (reliability) - it is clear that no one will waste your nerves on unstable applications!


Separation of responsibility, code reuse, testability


The most important element here is the Separation of Concerns: different ideas should be separated . If we want to change something, we don’t have to go to different parts of the code.


Without shared responsibility, neither Code Reusability nor Testability is almost impossible to implement.


The key is independence , as Uncle Bob noted in Clean Architecture. For example, if you use the library to upload images, you do not want to use another library to solve the problems created first! Independence in the architecture of the application - partially realizes scalability and maintainability.


Model View Controller


The MVC architecture has two options: a supervisor controller (supervising controller) and a passive view (passive view) .


In the mobile ecosystem, the implementation of the controller-supervisor is almost never encountered.


The MVC architecture can be characterized by two points:




The diagram illustrates the ideology of the pattern. Here, the presentation defines both listeners and callbacks; the view passes the input to the controller.


The controller accepts input data, and the view - the output, but a large number of operations occur between them. This architecture is well suited only for small projects.


MVC passive presentation



The main idea of ​​the passive MVC view is that the view is completely controlled by the controller. In addition, the code is clearly divided into two levels: business logic and display logic:



Display logic - how the application looks

Massive view controller


It is impossible to treat Activiti as a view . It is necessary to consider it as a display layer, and make the controller itself in a separate class.


And in order to reduce the code of the view controllers, you can split the views or define subviews with their own controllers. Implementing the MVC pattern in this way makes it easy to break the code into modules.


However, with this approach, there are some problems:



The solution to these problems lies in the creation of an abstract interface for the presentation. Thus, the presenter will only work with this abstraction, not the presentation itself. Tests will be simple, and problems solved.


All this is the main idea of ​​MVP.


Model View Presenter


This architecture facilitates unit testing, the presenter is easy to write tests, and can also be reused because the presentation can implement multiple interfaces.


From the point of view of how best and more correctly to create interfaces, it is necessary to consider MVP and MVC only as basic ideas, and not development patterns.



Use cases


Creating use cases is the process of putting business logic into separate classes, making them part of the model. They are independent of the controller and each contains one business rule. This increases reusability and makes writing tests easier.



In the GitHub example, in the login controller, the use case of validation and the use case of the login are passed. Login makes a connection to the network. If there are general business rules in other controllers or presenters, it will be possible to reuse these use cases.


View Bindings


There are four linear functions in the MVP implementation that do nothing except small changes in the user interface. You can avoid this extra code by using view binding .


All ways of binding can be found here .


Here is a simple approach: it is easy to test, and it is even easier to present the elements of the presentation as parameters via the interface, and not functions.


It should be noted that from the point of view of the presenter - nothing has changed.


Model View View-Model


There is another way of binding: instead of binding the view to the interface, we bind the elements of the view to the parameters of the view model — such an architecture is called MVVM. In our example, the email, password, and markup fields are defined using bindings. When we change the parameters in our model, changes are also made to the markup.



ViewModels are simple to write tests, because they do not require writing mock objects — because you change your own element and then check how it has changed.


Model View Intent


Another element that you can enter in an architecture is usually called MVI.



If you take any markup element, such as a button, you can say that the button does nothing, except that it produces any data, in particular, it sends information that it is pressed or not.


In the RxJava library, what creates events is called observable, that is, the button will be observable in the reactive programming paradigm.


But TextView only displays some text and does not create any data. In RxJava, elements that only accept data are called consumer .


There are also elements that do both, that is, that is, they both receive and send information, such as TextEdit. Such an element is also the creator (producer) and receiver (receiver), and in RxJava it is called subject .


With this approach, everything is a stream, and each stream starts from the moment a producer begins to emit information, and ends at a receiver, which, in turn, receives information. As a result, the application can be viewed as data streams. Data streams are the main idea of ​​RxJava .


Conclusion


Despite the fact that the implementation of the division of responsibility requires effort, it is a good way to improve the quality of the code as a whole, to make it scalable, easy to understand and reliable.


Other patterns, such as MVVM, removal of the template code, MVI can improve scalability even more, but make the project dependent on RxJava.


Also, it should be remembered that you can select only a part of these elements, and configure them for the final application depending on the tasks.


All source code can be found here .


')

Source: https://habr.com/ru/post/344184/


All Articles