A well-designed architecture is important to keep a project maintainable in the long term. At Shaadi, we have always strived to achieve it and in this process have transitioned from MVC to using MVVM pattern. While it’s debatable that MVVM does scale averagely in the long run, there’s a pattern that knits out this dilemma. This enhanced architecture is known as VIPER.
What is VIPER?
VIPER is an application of the Clean Architecture to iOS projects. It stands for View, Interactor, Presenter, Entity, and Router. It’s a really segmented way to divide responsibilities, fits very well with unit testing and makes your code more reusable.
- View delivers user actions to presenter.
- Presenter then delivers these actions to either interactor or router.
- If the action requires computation, interactor handles it and returns the state to the presenter.
- Presenter then transforms this state to presentation data and updates the view.
- Navigation logic is encapsulated in router and presenter is responsible from triggering it.
What’s our main goal?
Our first goal is to separate UI and business logic. Therefore, we can easily update UI without breaking any business rules and also test business logic in isolation. Both MVVM and VIPER assures this but in different ways. If we look from this point of view, they are structured as follows.
While MVVM has only a view component in UI layer, VIPER separates UI responsibilities into 3 components, which are View, Presenter and Router. It’s also obvious that the business layer looks pretty much the same.
Comparing to MVVM, Viper has a few key differences in the distribution of responsibilities: – It introduces the router, the layer responsible for the navigation flow, removing it from the View. – Entities are plain data structures, transferring the access logic that usually belongs to the model to the interactor. – ViewModelController responsibilities are shared between interactor and presenter.
VIPER sums up a few things that need to be maintained:
- View event management
- Data event management
- Event and business transformation
- Summarise each business use case
- Layered isolation within the module
- Inter-module communication
And here, you can further subdivide some of the responsibilities. VIPER has actually diluted the concept of Controller. The split parts have a clear single responsibility. Some parts are completely isolated. They should clearly distinguish their respective responsibilities during development. Instead of treating them as Controller.
VIPER is characterised by clear responsibilities, fine granularity, and clear isolation relationships, which can bring many advantages:
- Good testability. UI tests and business logic tests can be performed separately.
- Easy to iterate. Each part follows a single responsibility and can clearly know where the new code should be placed.
- High degree of isolation and low coupling. The code of one module does not easily affect another module.
- Easy teamwork. Each part of the division of labor is clear, teamwork is easy to unify the code style, you can quickly take over other people’s code.
Application in Shaadi app:
We have recently introduced VIPER in our projects and it gave a lot of ease and accessibility to perform better coding. Alongside, it has also helped to identify the areas for debugging or the addition of code. VIPER indeed is in for a long run!
MVC 📗 → MVVM 📘 → VIPER 📙
As you can see, MVVM and VIPER might be different but are not necessarily exclusive. The MVVM pattern only says that, besides view and model, there should be a view model layer. But it doesn’t say how this view model is created, nor how the data is retrieved – not all responsibilities are clearly defined. It’s open and can be implemented in many different ways.
On the other hand, VIPER is very specific software architecture. It contains layers with their own responsibilities and is less open to change. As we saw in this example, VIPER can also use view models, which are created by its presentation layer.
When it comes to choosing one or the other, there’s no silver bullet – but certainly a few pieces of advice. If you are in a long-term project with well-defined requirements and intend to reuse components, then VIPER is definitely a better option. The clearer separation of concerns improves testability and reusability.
But if you are prototyping or in a shorter project with no need to reuse components, MVVM is a better fit. With VIPER, you might need to create a lot of classes and protocols for small responsibilities (think of an “About Us” screen). MVVM generally produces much less code due to its not-so-clear separation of concerns and can avoid some overhead created by VIPER. Your code will definitely be easier to write, and still, be easy to test and maintain.