VIPER. Basic concepts
Start with VIPER Architecture pattern. How does it work? How to implement it? cons and pros of VIPER. Theoretical conclusions.
If you are reading this, that means that you heard about VIPER architecture and you want to understand how it works, cons and pros of VIPER and which project needs VIPER architecture?
I read many articles about VIPER and I didn’t find an explanation of how it should work instead of explaining some concrete implementation of this architecture. And this is why I will try to clarify how it should work in general.
A fast explanation of each module:
- V(View/ViewController) —layer for handling user interactions, creating layout.
- P(Presenter) — layer for converting and preparing results of business logic to display on V layer.
- I(Interactor) — layer for fetching data from Network services, cache. Main business logic layer.
- R(Router) — layer for the logic of navigation between other VIPER modules.
- E(Entity) — E(Entity) — Models (local or domain), actual data.
Protocols part in VIPER — the main part
For great testability and maintaining, we need to create abstract protocol connections between modules. It is an urgent part here.
On a picture above, presented a wrong connection between module, because these 2 modules need to know about actual classes of presenter and view. So if all our VIPER modules will be connected like this it will be hard to change some modules on another module without huge rebuilds. Also, it will be difficult to change, for example, the presenter without changing view and so on. All of this problem point to broken clean architecture concepts.
Protocols can help us in creating this abstraction. Let’s create 2 protocols for the presenter and view.
Now we can create 2 our classes for conforming to these protocols.
So what’re the problems solved here? At first — we can create any class, for example, SecondViewController and after conforming FirstViewProtocol to it — it will be possible to use this class instead of our FirtViewController. It is possible because our presenter looks on view, like on FirstViewProtocol, it is just an abstraction and any class can conform to this protocol and replace the old view. All things that another class can know about FirtViewProtocol that it must be a class and it must have setTextToLabel method and that’s it. All implementation can be different in different classes that conform to this protocol. So if you will need to replace the old view on some new view — you can simply conform FirstViewProtocol to your new ViewController and it won’t affect other parts of VIPER (presenter, interactor, router, etc).
So for default VIPER we just need to create 5 protocols:
1 — for communication between view and presenter.
2 — for communication between presenter and view.
3— for communication between presenter and router.
4 — for communication between presenter and interactor.
5 — for communication between interactor and presenter.
So each protocol contains only minimum properties and methods for being a concrete module. For example, protocol FirstViewProtocol need only presenter: FirstPresenterProtocol and setTextLabel method. So any class can conform to this protocol and replace the old view.
Pros of VIPER:
- Each module has strong responsibilities. It’s easy to change one module without changing another. (single responsibility principle).
- It’s easy to develop parts with a few developers. (If protocols created — that you can create the view which will communicate with presenter abstract class and another developer can create presenter for working with abstract view class.
- Testability (You can simply create a mock interactor class with confirmed protocol and it is easy to replace real interactor on mock interactor in test mode).
- High Maintenance. It is easy to maintain because you know what and where it should be. (View creation in view, text formating in the presenter, data fetching in interactor, navigation between modules in the router.
- Nice for Test Driven Development (TDD).
Cons of VIPER:
- For VIPER you need to create tons of boilerplate code. Even for the simple screen, you need to create at least 5 protocols and 5 classes for codebase consistency.
- It takes a lot of time. (You need to separate one screen on abstractions and 5 modules).
- You need a good understanding of ARC. because all modules have references on each other and you need to define which references must be weak.
- The bad pattern for always changing business goals and technical specifications. (You need to change a lot of protocols and classes in these conditions).
In this article, I tried to clarify what is VIPER and how his modules communicate with each other. So if you want to create an app in TDD way with defined business goals. If you need easy testability, maintainability, and scalability — VIPER is a great choice to separate your modules to different layers and give them an abstraction with strong responsibilities. VIPER is a bad idea for small startups without testing and with priorities and business goals which can change at any minute.