There are four major architectural patterns in iOS environment and all of them have been demystified by Bohdan Orlov. I’ll try to point out the main difference between MVC, MVP, MVVM, and VIPER that might be instrumental while building the appropriate architecture for your application.
The Model-View-Controller Pattern
I think this is the fundamental pattern that has proven itself as a useful tool in multiple technologies, contributed to their development, and is generally a helpful assistant for developers. If you ask architects what the best way to realize this pattern, most likely you’ll get all different versions and solutions. A significant feature of all the patterns is the detachment of UI from the coding logic which allows designers to do their job without having to consider the code.
The first emergence of the MVC pattern is attributed to the SmallTalk language. It required an architectural solution capable of separating UI elements from the domain logic and domain logic from the data. Thus, MVC in its original view consists of three categories that constitute its name. The breakdown helps us better understand the entities, reuse them, and test them in isolation. Let’s take a look at the categories:
- Model is the category of domain data access and manipulation. Domain logic.
- View is the category responsible for the graphical user interface elements. UI.
- Controller is the intermediate category between the other two. It changes Model according to the actions in View and adjusts View in response to the changes of Model. Realizes Use Case.
By dividing the entities into pattern components, we can define their contribution to a good architecture, which has the features of balanced duty distribution, susceptibility to testing, and inexpensive maintenance.
The main idea behind this pattern is that Controller and View depend on Model but Model does not depend on them. This is what makes it possible to develop and test the Model regardless of the View and Controller. Best case scenario is Controller having nothing to deal with View and View might have multiple Controllers to switch between. The same way, Controller may be used for multiple Views. For example, a Controller might depend on the user logging in. The user sees the View and creates some input data that gets transferred to the Controller while subscribing to notifications from the Model. The View receives updates from the Model and presents its last state to the user.
The Model-View-Presenter Pattern
This pattern also consists of three components. The chart below demonstrates that the View does not have to subscribe to the Model updates, the Controller (now Presenter) notifies the View about updates. This approach allows the creation of abstract View. The realization of the MVP pattern can be done by factoring out the View interfaces. Each View will then have their interfaces with certain sets of methods and properties that the Presenter requires. This interface is initialized with the Presenter which subscribes to the View event notifications and submits the data when necessary. This approach allows the use of TDD (Test-driven Development) methodology in application development.
The Model-View-ViewModel Pattern
This MVVM and MVP patterns realization looks pretty simple and similar at the first sight. However, for MVVM, the View to ViewModel connection is automatic while MVP requires some programming actions for that. It seems like MVC has more opportunities of View control.
The VIPER Pattern
The last nominee is particularly interesting because it does not belong to the MV(X) category. At this point I believe you agree that separation of duties is a good thing. VIPER takes another step towards that separation and offers five layers instead of the usual three.
- Interactor contains domain logic that is connected to the Entities, for example, the creation of new entity instances or their retrieving from the server. For these purposes you better use some Services and Managers that are treated more like external dependencies, not parts of the VIPER module.
- Presenter contains domain logic attached to the UI and calls out for methods on the Interactor.
- Entities are simple data objects, not related to the data access layer which is the Interactor responsibility.
- Router manages transitions between the VIPER modules.
As a matter of fact, a VIPER module can be your app’s screen or the entire user story. For example, authentication process can take one screen or several consecutive screens. It’s up to you to figure out the optimal size of your module.
These are the core separation of duties differences between VIPER and MV(X)-like patterns:
1. Model-based logic shifts to the Interactor level.
2. Entities are data structures that stay idle.
3. Presenter does not alter the data, but has Controller/Presenter/ViewModel UI representation duties migrated into it.
VIPER is the first template to tackle the navigation problem and it utilizes Router for that.