📜 ⬆️ ⬇️

Introduction to VIPER

At Mutual Mobile, testing is part of creating great software. However, testing was not always the key part when creating apps for iOS. When we started looking for ways to improve the testing of our applications, we found that writing tests for applications is quite difficult. And we decided that if we are going to improve the way we test software, we must first come up with a better way to design applications, and we called this solution VIPER.

The traditional way to design an iOS application is to use the MVC pattern (model-view-controller). Using MVC for an application architecture may suggest that each class is a model, or view, or controller. Since much of the application logic is not included in the model or view, it usually ends up in the controller. This leads to a problem known as Massive View Controllers , where controllers end up doing too much. If all the logic is embedded in the view controller, this leads to testing the logic through the UI, which in turn is the wrong way to design the logic. It is also easier to combine business logic and UI code in the same method. When you need to add new functionality or correct an error, it will be difficult to determine where to make the change and at the same time be sure that there will not be unpredictable consequences elsewhere.



VIPER


Looking for a better way to design an iOS application, I came across Clean Architecture , as described by Uncle Bob . Clean Architecture divides the logical structure of the application into different levels of responsibility. This makes it easier to isolate dependencies (for example, your database) and test interactions at the boundaries between levels.
')
VIPER is our implementation of Clean Architecture for iOS applications.

The word VIPER is a backronym for View, Interactor, Presenter, Entity and Routing.

VIPER structure


In short, you have:

Initially, my colleagues referred to this architecture as a VIP architecture. In a sense, this is a violation of rights, because it can be interpreted as a “Very Important Architecture”. Since I do not want people to think that other architectural solutions are not important, I decided to call her VIPER and later came up with what E and R would mean.

This separation is also consistent with the principle of Single Responsibility . Interactor is responsible for business intelligence, Presenter is responsible for the display, and View is responsible for the visual presentation.

Below is a diagram of the various components and how they are related:

image

Interactor / Interactor


Interactor is a simple case in the application. It contains business logic for managing objects (Entity) to perform a specific task. The task is performed in Interactor, regardless of any UI. The same Interactor can be used in iOS applications or console applications for Mac OS.

Because Interactor is PONSO (Normal NSObject), which primarily contains logic, and it is easy to develop using TDD (Development through Testing).

Entity / Entity


Entities are objects that Interactor manages. Entity only manages Interactor. It never passes entities to the presentation layer (i.e., Presenter).

Data Store / Data Store


Data Store (for example, web service, database) is responsible for providing Entity to Interactor. Because Interactor applies its business logic, it will fetch the Entity from the data store, manage the Entity, and then return the updated Entity back to the data store. The data store manages the persistence of the entity. Entity do not know about the data warehouse, so they do not know how to persist.

When using TDD (Development Through Testing) for Interactor development, it is possible to disable production data storage using double / mock tests. Without accessing a remote server (for a web service) or a disk (for a database) allows your tests to be repeatable and fast.

Presenter / Presenter


Presenter is PONSO, which basically consists of logic to control the UI. It collects input from user interaction, so it can send requests to Interactor. Presenter also gets the results of Interactor and converts the results to the state that is most effective for display on the View.

Entities are never transferred from Interactor to Presenter. Instead, simple data structures that have no behavior are transferred from Interactor to Presenter. This prevents any real work in Presenter. Presenter can only prepare data for display on the View.

View / View


View is passive. It waits for Presenter to transfer content for display; she never requests data from Presenter. The methods defined for the view (for example, the LoginView for the login screen) should allow the Presenter to communicate at a higher level of abstraction, expressed in terms of its contents, rather than how the content will be displayed. The presenter is not aware of the existence of UILabel, UIButton, etc. Presenter only knows about the content that it supports and when it needs to be displayed. Presenter needs to determine how content is displayed.

View is an abstract interface defined in Objective-C using a protocol. UIViewController or one of its subclasses implements the View protocol. For example, it could be a login screen:

@protocol LoginView <NSObject> - (void)setUserName:(NSString*)userName; - (void)setPassword:(NSString*)password; - (void)setLoginEnabled:(BOOL)enabled; @end @interface LoginViewController : UIViewController <LoginView> … @end 


Wireframe / Frame


Routing handles navigation from one screen to another, as defined in the wireframes created by the interaction designer. The wireframe object is responsible for routing. The wireframe object owns UIWindow, UINavigationController, etc. objects. He is responsible for creating the Interactor, Presenter and View / ViewController and for setting the ViewController. Since Presenter contains logic to respond to user input, Presenter knows when to go to another screen. Wireframe knows how to do it. So Presenter is a Wireframa user.

Example


You can find the Counter application, a simple application that demonstrates the use of Interactor, Presenter and View. The next article will describe in more detail how this application was developed. Additional articles will illustrate the use of data storage and Wireframe.

Feedback


In this way, VIPER helps us to be more precise as regards the separation of problems, dividing a large amount of code from one class into several smaller classes. By maintaining the sole responsibility in each class, it will simplify class development using TDD, which allows us to respond more quickly to changing requirements and create better software.

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


All Articles